Aguilera

  • 2020-08-10
  • 发表了主题帖: C2000在实时控制系统的常见问题

    讲师: 鲍震   德州仪器嵌入式处理器和汽车业务拓展经理   张万凌 德州仪器技术专家委员会委员,资深微控制器现场应用工程师     常见问题: 1、请问dsp在烧写程序过程中总是有芯片被锁而导致不能下载程序,有什么好的解决方法? A:请保证烧写过程的3.3v电源稳定,并使用正规厂家的烧写器。我们客户有非常大量烧写也不会出现被锁 2、C2000在控制应用方面有哪些解决方案? A:C2000有非常完善丰富的例程参考,请TI网站下载Controlsuite资料包,电机控制和电源控制领域主流大部分是C2000。 3、实时控制方面,是否可以举个形象的例子来说明他的实时性? A:比如数字电源,可以把C2000的PWM,ADC,COMP配置成 像硬件模拟器件一样完全独立实时运行 4、这个芯片与28035相比有什么优势? A:比28035强太多。100MHZ,256K FLASH,50K RAM,纯浮点。集成新的外设,比如 3路 独立ADC, 7 路运放,FSI高速通讯等等很多。具体请详见规格书 5、c2000是属于mcu还是dsp领域?内涵dsp,那么c2000是不是是不是双核应用? A:C2000系列是DSP核,但是集成丰富外设,可以像MCU一样应用。C2000有双核型号选择 6、目前contel-M系列mcu功能、速度都很强大了,ti还在大力推广c2000,他的优势在哪里?主要应用于那些领域? A:C2000的实时控制能力还是比Con-M强大,实际指令执行速度快,还有独特唯一的硬件外设。电机和电源控制都非常强 7、C2000实时响应速度在什么水平? A:同样主频下,C2000+CLA 实际运算性能可以达到Con-M核的2~3倍。 8、如何根据ADC计算实际值? A:根据ADC满量程3.3V对应的外部实际值,进行比例运算 9、实时控制系统肯定要解决实时性,主要技术指标有哪些? A:信号采集处理时间,要远远高于控制系统的变化时间 10、C2000微控制器系列产品如何让开发人员能够来规划他们的设计并重复使用代码? A:C2000系列所有芯片都是程序兼容的,很多寄存器都是配置一样 11、28035与ST的带DSP的单片机相比优势在哪里? A:DSP核的鼻祖就是TI,另外28035的PWM和ADC等等外设性能都更强 12、这个的CLA和F28377s的CLA一样吗? A:F28004x的CLA兼容28377的CLA程序,但是有更强的改进 13、I2C,CAN,SPI,SCI后面注明了Pin-Bootable,请问这与之前的280x系列有什么区别吗? A:以前的280X系列boot pin是固定引脚,F28004x的boot pin可以由用户自己选择任意引脚 14、请问F280004x这款芯片保密性能怎么样?还要外加保密芯片吗? A:保密性很强,很难**。双密码保护,密码位置用户自定义。 15、C2000实时控制的核心优势有哪些? A:DSP核是运算最快的微控制器,内置硬件浮点,复数,三角函数等加速器。 16、EPWM口有035多吗? A:比035多,有16路PWM并且全部集成Hi-PWM高精度性能 17、这个和以前的5000DSP最大差别在哪? A:集成丰富的外设比如驱动PWM,采集ADC,运放OPA,通讯CAN等等。 18、这个芯片提供什么操作系统? A:TI自己的操作系统TI-RTOS 19、有了新的型号,28035、2835、2812等老点的芯片,会停产生吗?如果会大概什么时候停产,有些遗留产品对老芯片还是有需求的。如果停产,新出的型号方便替代老型号吗? A:目前没有计划停产,不用担心,因为还有很多客户的老产品在用 20、377的TMU和快速数学库哪个快?CLA和CPU可以一起使用TMU吗?会出现互相等待的情况吗? A:TMU快的多,因为是硬件运算。CPU可以使用TMU 21、c2000 与 c6000的区别在那些方面 A:C2000集成很多外设,可以像MCU一样做微控制器 22、C200的 ADC 转换率是多少? A:最高有12Mbps的速率,一般常见都是4Mbps 23、C2000代码如何加密? A:硬件支持客户自设128bit密码,双密码 24、ccs6以上,导入ccs3.3老例程,提示的错误,是头文件路径的原因? A:对,C3.3的头文件路径在C6需要重新设置 25、C2000 DSP如何下载程序,一定要JTAJ接口配合配合仿真器下载吗? A:还有专用的烧写器。或者通过BOOT串行通信。 26、感觉c2000相对cortex m4 或者m7优势不大,而价格更贵,开发工具局限于ccs,arm则可以使用gcc A:C2000比M4/M7的实际运算能力更快,另外比M4/M7有独特的外设功能,发挥电机和电源的特殊应用。C2000也可以用GCC 27、04x的主频是多少? A:CPU 是100MHZ浮点,同时CLA 也是100MHZ 浮点 28、以前是2407做的步进电机控制,是否可以直接采用C2000来进行升级替换,改动的部分大吗? A:2407也是C2000系列,移植到新的C2000芯片改动不大 29、看新闻报道:C2000在性能超过了FPGA。请问只是在软件上么?C2000微结构做了哪些调整? A:F28004x 和 F2837X 确实内置了一些新硬件,可以实现FPGA的功能。 30、请问C2000系列产品有没有批量使用?主要用在哪些领域? A:已经使用十几年了,电机和电源控制领域的主导 31、c2000在实时处理跟FPGA有什么不同? A:C2000是MCU,但是新的产品内置硬件单元,确实能实现FPGA一些功能 32、C2000实时控制是否支持多路控制? A:当然可以,体现C2000的运算能力和外设丰富  

  • 回复了主题帖: TMS320F2812DSP的嵌入式温度测量系统

    初始化工作需要首先复位ADC转换模块,将RESET寄存器设置为1,3个时钟周期后,RESET位自动恢复为0,这时可以修改其他ADC寄存器。然后将SUSMOD寄 存器设置为0,ADC运行在模式0下,即忽略仿真悬挂模式;然后设计采样窗口长度,将ACQ_PS0寄存器设置为0;然后设置CPS寄存器,即ADC内核时钟定标器,设置 其时钟为外围时钟HSPCLK;设置ADC连续运行模式,即将CONT_RUN寄存器设置为1;设置级联排序模式为单排序模式,SEQ1和SEQ2工作在单16路排序器模式 下,将SEQ_CASC设置为1;设置ADCBGRFDN寄存器,将带隙和参考电路电源开;设置ADCPWDN 寄存器,将ADC内核的模拟电路电源开;设置ADCCLKPS寄存器,将内核时钟定标;设置SMODE_SEL寄存器为1,将采样模式设置为同时采样模式;设置CONV寄存器,定义一次自动转换时的最大转换数。

  • 回复了主题帖: TMS320F2812DSP的嵌入式温度测量系统

  • 发表了主题帖: TMS320F2812DSP的嵌入式温度测量系统

    本帖最后由 Aguilera 于 2020-8-10 22:05 编辑      为了实现嵌入式温度测量系统,提出了基于MZBB-2铂薄膜热敏与TMS320F2812DSP控制芯片的嵌入式解决方案,完成了该系统的硬件设计与软件设计。系统硬件组成包括TMS320F2812DSP处理器、FPGA控制器、ADC转换电路等部分,其中TMS320F2812DSP处理器是控制系统的核心,该芯片通过片上寄存器控制负责ADC转换的控制工作,并且完成电阻数据采集、温度计算,并且将温度测量结果由通信系统发送给控制系统。实验结果表明,温度测量精度达到设计要求,满足了实时温度采集的要求,该方案运行稳定可靠,具有广泛的应用前景。温度是日常生活中一个重要的物理量,是工农业生产及科学实验中需要测量的重要参数[1-2]。在航空、航天领域中,由于温度变化对设备可能产生影响,包括降低系统的成像质量,影响分辨率,因此,在这些系统中对温度的控制十分重要[3-4]。MZBB-2铂薄膜热敏电阻器是由特定的金属氧化物按一定比例混合压制形成的温度传感器件,MZBB-2铂薄膜热敏电阻器具有体积小、灵敏度高、响应快及稳定性好等优点,其标称值为100 Ω(Pt100)、500 Ω(Pt500)、1 000Ω(Pt1000)3种。该系列铂薄膜热敏电阻器耐振动、冲击及潮湿、工作寿命长,因而可满足军事、科技等领域中对温度测量、控制及补偿要求[5-6]。MZBB-2系列铂薄膜热敏电阻器为片式结构,引线采用0.2mm 的铂丝,外表面为玻璃釉包封。因此可直接将其贴覆在被测物体的表面,也可将其镶嵌在槽内,还可以封装于金属或陶瓷套管内,用于不同的温度测量场合。     根据实际项目的使用要求,使用TI 公司的TMS320F2812DSP处理器与MZBB-2温度传感器组成了温度测量系统,其中ADC转换部分由DSP芯片通过片上      寄存器完成,阻值测量及温度计算由DSP处理器完成,并将温度测量结果发送给控制系统。该方案满足了对系统对温度测量的准确性与速度要求,工作稳定可靠。  

  • 2020-08-09
  • 发表了主题帖: C2000™ Piccolo™ Workshop

     

  • 发表了主题帖: 关于28377d双核仿真与CLA仿真经验

            由于28377D有两个CPU和两个CLA,仿真起来会比较麻烦。记录下仿真时候的操作。    在进行CPU2仿真时,因为CPU2是通过CPU1来启动的,CPU1中需设置CPU2启动 模式,先把.out烧入至CPU1,连接CPU2烧入.out,先run CPU2 再run CPU1,这时还不能正常仿真,reset CPU1(reset CPU restart)再run CPU1, CPU1可以仿真跑了, 然后reset CPU2 (reset CPU restart)再重新run CPU2就可以对CPU2正常仿真了。      由于CPU和CLA是并行运行,仿真和普通CPU仿真不一样。先connect CPU ,load CPU 的.out文件,然后connect CLA,load 相同.out symbol(load .out 时可选文件类型)。在CLA 程序中加入__mdebugstop() 当做断点使用。CLA仿真时,程序会跑到该软件断点,可以单步调试。     注意:当CPU1和CPU2之间有用到IPC通信时,仿真前先把InitialiIpc()注释掉。因为IPC 通信时会同步CPU1和CPU2,仿真运行时会一直等在while中。

  • 2020-08-08
  • 发表了主题帖: TI的多核异构结构的SOC平台AM57XX

            TI的新一代处理器平台AM57XX是多核异构结构的SOC,片上有一到两个ARM核(ARM CORTEX-A15)和一到两个DSP(C66x)核。AM57xx处理器是高度集成的器件,可用于实现高性能和多媒体应用。板载加速器提供加速视觉和深度学习功能,支持多个工业以太网协议和视频处理。多核SOC的软件相对单核系统比较复杂,TI的AM57XX的软件包是processor sdk。 SDK默认ARM 跑LINUX系统,DSP跑OPENCL Monitor。ARM通过OPENCL接口使用DSP,DSP起到加速运算的作用,如下图所示: 图1,基于OPENCL的工作方式 很多客户希望自主使用DSP,不用OPENCL框架。TI也提供了基于IPC的ARM DSP工作框架,如下图所示: 图2,基于IPC的工作方式 本文介绍图2的工作方式和操作步骤。本文编译工作都是在一台LINUX PC上操作,建议操作系统使用UBUNTU1604或者1804版本。本文基于Processor SDK 06.01.00.08版本操作,其他版本SDK操作步骤大致相似。分步骤操作如下: 1,安装AM57XX RTOS SDK和LINUX SDK。 点击下面链接下载LINUX SDK 在UBUNTU系统下,首先通过chmod +x ….给下载文件一个可执行权限,然后./xxx执行这个安装包,根据提示安装到默认目录。 同理,安装LINUX版本RTOS SDK。 在UBUNTU系统下,首先通过chmod +x ….给下载文件一个可执行权限,然后./xxx执行这个安装包,根据提示安装到默认目录。 RTOS SDK安装好后会在/home/xxx/ti目录下出现如下文件: 2,安装LINUX版本CCS   下载这个文件到UBUNTU系统: 下载解压后会得到如下文件: 在UBUNTU桌面系统中(注意要登录桌面,不要远程控制台登录),通过控制台执行./ ccs_setup_9.2.0.00013.bin,然后根据提示把CCS安装到/home/xxx/ti目录。 注意:第一次打开CCS会问是否需要导入RTOS安装的一系列组件,选择“是”。 3,新建开发板启动SD卡,编译kernel。 准备一张空白SD卡,插入USB转SD工具,将工具插入UBUNTU PC USB口。然后通过控制台进入ti-processor-sdk-linux-am57xx-evm-06.01.00.08\bin,执行./ create-sdcard.sh。根据提示选择SD卡,最终得到一张可以用于启动的SD卡。 把这张卡插入AM5728 IDK,上电可以正常启动LINUX系统。 在ti-processor-sdk-linux-am57xx-evm-06.01.00.08路径下,执行make linux可以把LINUX kernel重新编译。 4,编译IPC EXAMPLE。本文要编译的DEMO路径是:ti\ipc_3_50_04_07\examples\DRA7XX_linux_elf。首先到ipc_3_50_04_07目录编辑products.mak 设置TOOLCHAIN_LONGNAME,TOOLCHAIN_INSTALL_DIR,TOOLCHAIN_PREFIX,KERNEL_INSTALL_DIR等参数。 进入processor_sdk_rtos_am57xx_6_01_00_08目录,编辑makefile如下: 在processor_sdk_rtos_am57xx_6_01_00_08目录执行./setupenv.sh && make ipc_example,如果一切顺利可以在\ipc_3_50_04_07\examples\DRA7XX_linux_elf目录下获得编译好的DEMO binary文件。 5,本文测试ex02_messageq这个DEMO,在DRA7XX_linux_elf目录下找到如下文件复制到开发板上LINUX系统。 App_host是ARM LINUX跑的软件,server_xxx分别是在DSP1/2,IPU1/2上面跑到软件。把server_xx这几个文件复制到/lib/firmware下面。删除现有的dra7-dsp1-fw.xe66,dra7-dsp2-fw.xe66,dra7-ipu1-fw.xem4,dra7-ipu2-fw.xem4软连接。然后重新建立软链接: ln -s server_dsp1.xe66 /lib/firmware/dra7-dsp1-fw.xe66 ln -s server_dsp2.xe66 /lib/firmware/dra7-dsp2-fw.xe66 ln -s server_ipu1.xem4 /lib/firmware/dra7-ipu1-fw.xem4 ln -s server_ipu2.xem4 /lib/firmware/dra7-ipu2-fw.xem4 重启系统。 分别执行:./app_host DSP1(DSP2,IPU1,IPU2),可以获得如下输入打印,说明运行成功: 6,进一步开发。进入./ti/pdk_am57xx_1_0_16/packages目录,执行source ./pdksetupenv.sh。修改pdkProjectCreate.sh 文件中的CCS路径如下: 执行“./pdkProjectCreate.sh AM572x all little all all dsp”创建DSP DEMO的CCS工程。 一切顺利可以在.\ti\pdk_am57xx_1_0_16\packages\MyExampleProjects目录创建一些CCS工程如下: 这些是基于TI RTOS的一些外设接口的DEMO软件,他们可以导入到CCS进行编译和调试,读者可以把需要的DEMO移植到IPC EXAMPLE里,从而实现自己DSP软件。 总结:本文介绍了如何编译测试AM57XX平台IPC的DEMO。首先需要安装UBUNTU操作系统的PC,并在UBUNTU下安装RTOS和LINUX SDK,然后安装LINUX版本CCS。软件安装完毕,需要修改编译脚本,先编译IPC EXAMPLE,然后创建基于CCS的DSP RTOS DEMO。后续需要读者把RTOS DEMO移植到IPC EXAMPLE从而实现自己的DSP软件。

  • 发表了主题帖: 关于DSP28335的SPI发送

    #include "DSP2833x_Device.h" #include "DSP2833x_Examples.h" unsigned char table[]={                   0xC0,  //"0"                 0xF9,  //"1"                 0xA4,  //"2"                 0xB0,  //"3"                 0x99,  //"4"                 0x92,  //"5"                 0x82,  //"6"                 0xF8,  //"7"                 0x80,  //"8"                 0x90,  //"9"                 0x88,  //"A"                 0x83,  //"B"                 0xC6,  //"C"                 0xA1,  //"D"                 0x86,  //"E"                 0x8E,  //"F"                 0x89,  //"H"                 0xC7,  //"L"                 0xC8,  //"n"                 0xC1,  //"u"                 0x8C,  //"P"                 0xA3,  //"o"                 0xBF,  //"-"                 0xFF,  //熄灭                 0xFF  //自定义                            }; void init(void) {  InitSysCtrl();  InitSpiaGpio();  EALLOW;  GpioCtrlRegs.GPBMUX2.bit.GPIO58=0;  GpioCtrlRegs.GPBDIR.bit.GPIO58=1;  GpioCtrlRegs.GPBMUX2.bit.GPIO59=0;  GpioCtrlRegs.GPBDIR.bit.GPIO59=1;  GpioCtrlRegs.GPBMUX2.bit.GPIO63=0;  GpioCtrlRegs.GPBDIR.bit.GPIO63=1;  GpioCtrlRegs.GPBMUX2.bit.GPIO62=0;  GpioCtrlRegs.GPBDIR.bit.GPIO62=1;  EDIS;  GpioDataRegs.GPBSET.bit.GPIO58=1;  GpioDataRegs.GPBSET.bit.GPIO59=0;  GpioDataRegs.GPBSET.bit.GPIO62=0;  GpioDataRegs.GPBSET.bit.GPIO63=1; } void delay(void) {  long int i,j;  for(i=0;i<1000;i++)   for(j=0;j<10000;j++); } void delay1(void) {  long int i,j;  for(i=0;i<10;i++)   for(j=0;j<10;j++); } void init_spi(void) {  SpiaRegs.SPICCR.bit.CLKPOLARITY=1; SpiaRegs.SPICTL.bit.TALK=1;//发送启动  SpiaRegs.SPICTL.bit.CLK_PHASE=0;  SpiaRegs.SPICTL.bit.MASTER_SLAVE=1;  SpiaRegs.SPICCR.bit.SPICHAR=0x0f;   SpiaRegs.SPIBRR =0x007F;  SpiaRegs.SPICCR.bit.SPISWRESET=1;  SpiaRegs.SPIPRI.bit.FREE=1; } void main(void) {  int k;  init();  init_spi();  while(1)  {   for(k=0;k<16;k++)   {    if(SpiaRegs.SPISTS.bit.BUFFULL_FLAG!=1)    {      SpiaRegs.SPITXBUF=table[k];      delay();    // delay();    }  // delay();    }  } }

  • 发表了主题帖: TI DSP 28335编程实例

    首先说明:开发环境Manjaro linux,内核5.0,滚动升级版本,随时都是最新,CCS也是最新的CCv 8 复制代码   1 #include "DSP2833x_Device.h"     // 这是一个很重要的头文件,决定CPU类型,数据类型、asm宏指令,包含的所有的外设,外设的头文件和其他硬件的抽象头文件   2 #include "DSP2833x_Examples.h"   // 该头文件是常用实现函数的文件包含   3   6 //中断服务函数声明   7 __interrupt void wakeint_isr(void);   8    9 //声明全局变量  12 Uint32 WakeCount;  13 Uint32 LoopCount;  14   15 //主函数  18 void main(void)  19 {  20     // Step 1. 初始化系统控制:  22     // 配置PLL,设置cpu时钟  23     // 配置外设时钟  24     // 配置看门狗 该函数在 DSP2833x_SysCtrl.c中.  25     InitSysCtrl();                                    26   27     // Step 2. 初始化GPIO:  29     // 该函数在 DSP2833x_Gpio.c 中.  32     //InitGpio();   33   34     // Step 3. 初始化中断:  36     // 禁止CPU中断,该函数在 DSP2833x_Device.h 中 38     DINT;  39   40     // 禁止外设中断  41     // 清理外设中断允许寄存器  42     // 清理外设中断标志寄存器  43     // 禁止CPU中断,设置允许中断位为0  44     // 初始化外设中断向量表  45     // 设置中断函数  46     InitPieCtrl();  47   48     //  49     // Disable CPU interrupts and clear all CPU interrupt flags  50     //  51     IER = 0x0000;  52     IFR = 0x0000;  53   54     //  55     // Initialize the PIE vector table with pointers to the shell Interrupt  56     // Service Routines (ISR).  57     // This will populate the entire table, even if the interrupt  58     // is not used in this example.  This is useful for debug purposes.  59     // The shell ISR routines are found in DSP2833x_DefaultIsr.c.  60     // This function is found in DSP2833x_PieVect.c.  61     //  62     InitPieVectTable();  63   64     //  65     // Interrupts that are used in this example are re-mapped to  66     // ISR functions found within this file.  67     //  68     EALLOW;            // This is needed to write to EALLOW protected registers  69     PieVectTable.WAKEINT = &wakeint_isr;  70     EDIS;   // This is needed to disable write to EALLOW protected registers  71   72     // Step 4. 初始化外设:  74     // 该函数在 DSP2833x_InitPeripherals.c 中  75     //  76     //InitPeripherals(); // Not required for this example  77   78     // Step 5. 用户自己的代码  80     // Clear the counters  84     //  85     WakeCount = 0;      // Count interrupts  86     LoopCount = 0;      // Count times through idle loop  87   88     //  89     // 将看门狗中断连接到PIE中断,该寄存器首SCM控制,使用特定的修改方式  90     // Write to the whole SCSR register to avoid clearing WDOVERRIDE bit  91     //  92     EALLOW;  93     SysCtrlRegs.SCSR = BIT1;  94     EDIS;  95   96     //  97     // Enable WAKEINT in the PIE: Group 1 interrupt 8  98     // Enable INT1 which is connected to WAKEINT:  99     // 100     PieCtrlRegs.PIECTRL.bit.ENPIE = 1;      // Enable the PIE block 101     PieCtrlRegs.PIEIER1.bit.INTx8 = 1;      // Enable PIE Group 1 INT8 102     IER |= M_INT1;                          // Enable CPU int1 103     EINT;                                   // Enable Global Interrupts 104  105     // 106     // Reset the watchdog counter 107     // 108     ServiceDog(); 109  110     // 111     // Enable the watchdog 112     // 113     EALLOW; 114     SysCtrlRegs.WDCR = 0x0028; 115     EDIS; 116  117     // 118     // Step 6. 函数执行环节 119     // 120     for(;;) 121     { 122         LoopCount++; 123  124         // 125         // Uncomment ServiceDog to just loop here 126         // Comment ServiceDog to take the WAKEINT instead 127         // 128         //ServiceDog(); 129     } 130 } 131  132 // 中断函数 133 // Step 7. Insert all local Interrupt Service Routines (ISRs) and functions  134 // here: If local ISRs are used, reassign vector addresses in vector table as 135 // shown in Step 5 136 // 137  138 // 139 // wakeint_isr - 140 // 141 __interrupt void 142 wakeint_isr(void) 143 { 144     WakeCount++; 145  146     // 147     // Acknowledge this interrupt to get more from group 1 148     // 149     PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; 150 } 复制代码

  • 发表了主题帖: TI TMS320F28335程序SVPWM源程序

    //***************************************************/ //文件名:SVPWM.c //功能:调用28335内部PWM模块生成SVPWM输出测试文件 //说明:输入信息采用结构体,使用时改变结构体指针即可改变输入信号。 //     InitSvpwm()函数提供PWM模块初始化以及相应PIE中断的配置。 //     通过park逆变换得到静止平面坐标系下的电压信号。 //     在PWM定时器下溢中断中更新比较器的值,即每个PWM周期更新一次 //****************************************************/ #include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File #include "DSP2833x_Examples.h"   // DSP2833x Examples Include File #include "math.h" #include "float.h"         extern Uint16 RamfuncsRunStart;         extern Uint16 RamfuncsLoadStart;         extern Uint16 RamfuncsLoadEnd;          typedef struct {    float ds;              // 静止平面坐标系下电压信号    float qs;    float ang;             // 电气角度 电气角度=机械角度*极对数    float de;              // 旋转坐标系下电压信号    float qe; }IPARK;   IPARK ipark1={0,0,0,0.3,0.4}; //  IPARK *v=&ipark1;       //改变此处结构体指针改变输入 void InitSvpwm(void); void InitEPwm1(void); void InitEPwm2(void); void InitEPwm3(void); interrupt void epwm1_isr(void); void ipark(IPARK *v); void svgen(IPARK *v); #define PRD  7500                // PWM周期寄存器 #define PI 3.1415926 float tmr1,tmr2,tmr3; void main(void) {    InitSysCtrl();    DINT;    InitPieCtrl();    IER = 0x0000;    IFR = 0x0000;       InitPieVectTable();         MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);                        //Flash operation<F28335.cmd>         InitFlash();                          InitSvpwm();    for(;;)    {        asm("          NOP");    } } void InitSvpwm(void) {      InitEPwm1Gpio();    InitEPwm2Gpio();    InitEPwm3Gpio();    EALLOW;    PieVectTable.EPWM1_INT = &epwm1_isr;       EDIS;    EALLOW;    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;    EDIS;    InitEPwm1();    InitEPwm2();    InitEPwm3();    EALLOW;    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;    EDIS;    IER |= M_INT3; // 使能中断 EPWM INT1 位于PIE中断分组3.1    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;    EINT;    ERTM; } interrupt void epwm1_isr(void) {    // 更新 CMPA 和 CMPB 寄存器值    svgen(&ipark1);    EPwm1Regs.CMPA.half.CMPA=tmr1;    EPwm2Regs.CMPA.half.CMPA=tmr2;    EPwm3Regs.CMPA.half.CMPA=tmr3;    EPwm1Regs.CMPB=tmr1;    EPwm2Regs.CMPB=tmr2;    EPwm3Regs.CMPB=tmr3;        // 清除中断标志    EPwm1Regs.ETCLR.bit.INT = 1;    // 清除中断响应    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } void ipark(IPARK *v) {   float  ang;   ang=(v->ang/360)*2*PI;                    //角度转化为弧度   v->ds=v->de*cos(ang)-v->qe*sin(ang);      //得到静止平面坐标系下d轴电压   v->qs=v->qe*cos(ang)+v->de*sin(ang);      //得到静止平面坐标系下q轴电压 } void svgen(IPARK *v) {    float Va,Vb,Vc,t1,t2,Ta,Tb,Tc;    Uint32 sector=0;                                               // sector=a+2b+4c 扇区状态标示 注意:setor的值1~6与扇区不是顺序对应    ipark(v);    Va=v->qs;                                                      // Va = Uq    Vb=(-0.5) * v->qs + (0.8660254) * v->ds;                       // Vb = 1/2*(sqrt(3)*Ud - Uq)         sqrt(3)/2=0.866    Vc=(-0.5) * v->qs - (0.8660254) * v->ds;                       // Vc = -1/2*(sqrt(3)Ud + Uq)    if(Va>0.0000001)                                               // 判断属于哪个扇区            sector=1;                                                      // Va>0 则 a=1;否则a=0    if(Vb>0.0000001)                                               //    sector=sector+2;                                               // Vb>0 则 b=1;否则b=0    if(Vc>0.0000001)                                               //    sector=sector+4;                                               // Vc>0 则 c=1; 否则c=0    Va=v->qs;                                                         Vb=(-0.5) * v->qs + (0.8660254) * v->ds;                         Vc=(-0.5) * v->qs - (0.8660254) * v->ds;      switch(sector){      case 1:                               //sector==1 对应扇区II        t1=Vc;        t2=Vb;        Tb=(0.25)*(1-t1-t2);        Ta=Tb+(0.5)*t1;        Tc=Ta+(0.5)*t2;            break;      case 2:                               //sector==2 对应扇区VI        t1=Vb;        t2=-Va;        Ta=(0.25)*(1-t1-t2);        Tc=Ta+(0.5)*t1;        Tb=Tc+(0.5)*t2;        break;      case 3:                               //sector==3 对应扇区I        t1=-Vc;        t2=Va;        Ta=(0.25)*(1-t1-t2);        Tb=Ta+(0.5)*t1;        Tc=Tb+(0.5)*t2;        break;      case 4:                               //sector==4 对应扇区IV        t1=-Va;        t2=Vc;        Tc=(0.25)*(1-t1-t2);        Tb=Tc+(0.5)*t1;        Ta=Tb+(0.5)*t2;        break;      case 5:                               //sector==5 对应扇区III        t1=Va;        t2=-Vb;        Tb=(0.25)*(1-t1-t2);        Tc=Tb+(0.5)*t1;        Ta=Tc+(0.5)*t2;        break;      case 6:                              //sector==6 对应扇区V           t1=-Vb;        t2=-Vc;        Tc=(0.25)*(1-t1-t2);        Ta=Tc+(0.5)*t1;        Tb=Ta+(0.5)*t2;        break;      default:                             //sector=0和sector=7时错误        Ta=0.5;        Tb=0.5;        Tc=0.5;    }    tmr1=Ta*PRD;    tmr2=Tb*PRD;    tmr3=Tc*PRD; } void InitEPwm1() {    // 配置时钟    EPwm1Regs.TBCTL.bit.CTRMODE = 0x2;             // 增减计数模式    EPwm1Regs.TBPRD = PRD;                         // 设置周期    EPwm1Regs.TBCTL.bit.PHSEN = 0x0;               // 禁用相位加载同步    EPwm1Regs.TBPHS.half.TBPHS = 0x0000;           // 相位初值    EPwm1Regs.TBCTR = 0x0000;                      // 计数初值    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x1;           // TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV)    EPwm1Regs.TBCTL.bit.CLKDIV = 0x1;    // 配置比较寄存器    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0x0;          //使用阴影寄存器          EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0x0;    EPwm1Regs.CMPCTL.bit.LOADAMODE = 0x0;          //计数器值为0时更新比较器值    EPwm1Regs.CMPCTL.bit.LOADBMODE = 0x0;    // 设置比较器初值    EPwm1Regs.CMPA.half.CMPA = 1875;                   EPwm1Regs.CMPB = 1875;                            // 模式设定    EPwm1Regs.AQCTLA.bit.ZRO = 0x1;               // 等于0时输出低    EPwm1Regs.AQCTLA.bit.CAU = 0x3;               // 计数值=比较值时输出取反    EPwm1Regs.AQCTLB.bit.ZRO = 0x2;               // 等于0时输出高    EPwm1Regs.AQCTLB.bit.CBU = 0x3;               // 计数值=比较值时输出取反    // 配置中断    EPwm1Regs.ETSEL.bit.INTSEL = 0x1;             // 计数值到0触发事件    EPwm1Regs.ETSEL.bit.INTEN = 1;                // 使能中断    EPwm1Regs.ETPS.bit.INTPRD = 0x1;              // 每次事件发生都触发中断 } void InitEPwm2() {    EPwm2Regs.TBCTL.bit.CTRMODE = 0x2;            EPwm2Regs.TBPRD = PRD;                      EPwm2Regs.TBCTL.bit.PHSEN = 0x0;             EPwm2Regs.TBPHS.half.TBPHS = 0x0000;            EPwm2Regs.TBCTR = 0x0000;                      EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0x1;         EPwm2Regs.TBCTL.bit.CLKDIV = 0x1;    EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0x0;             EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0x0;    EPwm2Regs.CMPCTL.bit.LOADAMODE = 0x0;       EPwm2Regs.CMPCTL.bit.LOADBMODE = 0x0;    EPwm2Regs.CMPA.half.CMPA = 1875;                   EPwm2Regs.CMPB = 1875;                            EPwm2Regs.AQCTLA.bit.ZRO = 0x1;                            EPwm2Regs.AQCTLA.bit.CAU = 0x3;                   EPwm2Regs.AQCTLB.bit.ZRO = 0x2;                EPwm2Regs.AQCTLB.bit.CBU = 0x3;                         EPwm2Regs.ETSEL.bit.INTEN = 0;                 //屏蔽中断                          } void InitEPwm3(void) {    EPwm3Regs.TBCTL.bit.CTRMODE = 0x2;             EPwm3Regs.TBPRD = PRD;                         EPwm3Regs.TBCTL.bit.PHSEN = 0x0;                EPwm3Regs.TBPHS.half.TBPHS = 0x0000;            EPwm3Regs.TBCTR = 0x0000;                   

  • 发表了主题帖: DSP 28335Control Suit点灯实验

    本帖最后由 Aguilera 于 2020-8-8 18:18 编辑 首先Example_2833xLEDBlink为官方TI公司所提供的代码 DSP2833x eZdsp LED Blink Getting Started Program. 能够发现自己的基础不是太好,主要是什么是 SARAM我都不知道。 【知识补充】 flash指闪存,比如内存卡就是用闪存芯片。 boot rom是启动系统包。 SRAM(Static Random Access Memory)与DRAM(Dynamic Random Access Memory)这是根据内存的工作原理划分出的两种内存。 SARAM在一个机器周期内只能被访问一次,而DARAM则在一个机器周期内能被访问两次。 【问题1】什么是boot,为什么dsp需要在启动时进行boot 从flash中加载程序啊,就像微机一样从硬盘加载到内存。 boot to SARAM 启动SARAM 控制GPIO32的 LED 进行闪烁 500msec 嗯 就是0.5闪烁一下啦 进行了实验可是GPIO的寄存器还是不够理解,需要重新看一下。

  • 发表了主题帖: TI dsp28335例程pwm讲解

    DSP28335共12路16位的ePWM,能进行频率和占空比控制。 ePWM的时钟TBCLK=SYSCLKOUT/(HSPCLKDIV&TImes;CLKDIV): PWM信号频率由时基周期寄存器TBPDR和时基计数器的计数模式决定。初始化程序采用的计数模式为递增计数模式。在递增计数模式下,时基计数器从零开始增加,直到达到周期寄存器值(TBPDR)。然后时基计数器复位到零,再次开始增加。 PWM信号周期与频率的计算如下: 端口对应关系 说明:JP0B的端口号按“Z”字形顺序数。 初始化程序注释 void InitPwm1AB(float32 f) { Uint16 T= 2343750/f-1.0;//系统时钟SYSCLKOUT=150MHz, TBCLK=6.6666667ns,在连续增计数模式下,f=150000000/(TBPDR+1) EALLOW; //先初始化通用输入输出口// GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; EPwm1Regs.TBPHS.half.TBPHS = 0; // 在相位寄存器中设置计数器的起始计数位置 //下面两条语句组合对PWM的时钟进行分频 EPwm1Regs.TBCTL.bit.CLKDIV = 6; EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; EPwm1Regs.TBPRD = T; //在周期寄存器中设置计数器的计数周期 //TBCTL为定时器控制寄存器 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //设置计数模式位为连续增计数模式,产生对称方波 EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 将定时器相位使能位关闭 EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;//映射寄存器SHADOW使能并配置映射寄存器为自动读写 EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 定时器时钟源选择,一共有四种时钟源 EPwm1Regs.CMPA.half.CMPA= 0.0001*T;// 设置EPWM1A比较值寄存器的比较值,即体现EPWM1A的占空比 EPwm1Regs.CMPB= 0.0001*T; EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;//A模块比较模式 EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;//B模块比较模式 EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // A模块比较使能, 通过写0来清除SHDWAMODE位来使能load on CTR=Zero EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // B模块比较使能, 通过写0来清除SHDWBMODE位来使能load on CTR=Zero //AQCTLA为输出A比较方式控制寄存器 EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR(计数器)计到零时使输出为反向 EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;//TBCTR(计数器)与CMPA在up计数时相等使输出为high,这关系的输出的占空比 EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; EDIS; } Dsp28335 - ePWM - 50Hz小舵机的控制 - 代码例程 使用dsp28335控制舵机,使用pwm信号。 28xx设置的sysclk为150MHz,大家用的时候主频一定要搞清楚,看看底层代码,TI的数据手册虽然是英文的但是看起来很容易,配置起来也很简单无脑。 初始化不多说,这里我用的pwm只是用的最基本功能,dsp中的ePwm模块的功能非常强大,很多功能我都使用不到,有需要的可以针对性的看下。 void InitEPwm3Gpio(void) { EALLOW; /* Enable internal pull-up for the selected pins */ // Pull-ups can be enabled or disabled by the user. // This will enable the pullups for the specified pins. // Comment out other unwanted lines. GpioCtrlRegs.GPAPUD.bit.GPIO4 = 0; // Enable pull-up on GPIO4 (EPWM3A) GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // Enable pull-up on GPIO5 (EPWM3B) /* Configure ePWM-3 pins using GPIO regs*/ // This specifies which of the possible GPIO pins will be ePWM3 funcTIonal pins. // Comment out other unwanted lines. GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; // Configure GPIO4 as EPWM3A GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1; // Configure GPIO5 as EPWM3B EDIS; } 这里使用的是GPIO4和GPIO5,其他引脚同理。为了提高驱动能力使用Pullup模式。 设置Mux寄存器为1选择ePWM功能。 void EPwmSetup(void) { InitEPwm3Gpio(); EPwm3Regs.TBSTS.all=0; EPwm3Regs.TBPHS.half.TBPHS=0; EPwm3Regs.TBCTR=0; //EPwm2Regs.CMPCTL.all=0x50; // Immediate mode for CMPA and CMPB EPwm3Regs.CMPCTL.bit.SHDWBMODE = 0x0; EPwm3Regs.CMPCTL.bit.SHDWAMODE = 0x0; EPwm3Regs.CMPCTL.bit.LOADBMODE = 0x0; EPwm3Regs.CMPCTL.bit.LOADAMODE = 0x0; EPwm3Regs.CMPA.half.CMPA = 6250; EPwm3Regs.CMPB=3125; //EPwm3Regs.AQCTLA.all=0x60; // EPWMxA = 1 when CTR=CMPA and counter inc // EPWMxA = 0 when CTR=CMPA and counter dec EPwm3Regs.AQCTLA.bit.CBD = 0x0; EPwm3Regs.AQCTLA.bit.CBU = 0x0; EPwm3Regs.AQCTLA.bit.CAD = 0x0; EPwm3Regs.AQCTLA.bit.CAU = 0x1; EPwm3Regs.AQCTLA.bit.PRD = 0x0; EPwm3Regs.AQCTLA.bit.ZRO = 0x2; //EPwm3Regs.AQCTLA.all = 0x0012; EPwm3Regs.AQCTLB.bit.CBD = 0x0; EPwm3Regs.AQCTLB.bit.CBU = 0x1; EPwm3Regs.AQCTLB.bit.CAD = 0x0; EPwm3Regs.AQCTLB.bit.CAU = 0x0; EPwm3Regs.AQCTLB.bit.PRD = 0x0; EPwm3Regs.AQCTLB.bit.ZRO = 0x2; //EPwm3Regs.AQCTLB.all = 0x0102; EPwm3Regs.AQSFRC.bit.RLDCSF = 0x0; EPwm3Regs.AQCSFRC.all=0x0; EPwm3Regs.DBCTL.all=0x0; EPwm3Regs.DBRED=0; EPwm3Regs.DBFED=0; EPwm3Regs.TZSEL.all=0; EPwm3Regs.TZCTL.all=0; EPwm3Regs.TZEINT.all=0; EPwm3Regs.TZFLG.all=0; EPwm3Regs.TZCLR.all=0; EPwm3Regs.TZFRC.all=0; EPwm3Regs.ETSEL.all=0; // Interrupt when TBCTR = 0x0000 EPwm3Regs.ETFLG.all=0; EPwm3Regs.ETCLR.all=0; EPwm3Regs.ETFRC.all=0; EPwm3Regs.PCCTL.all=0; EPwm3Regs.TBPRD=62499; EPwm3Regs.TBCTL.bit.FREE_SOFT = 0x2; EPwm3Regs.TBCTL.bit.CLKDIV = 0x2; EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0x6; EPwm3Regs.TBCTL.bit.SYNCOSEL = 0x3; EPwm3Regs.TBCTL.bit.PRDLD = 0x0; EPwm3Regs.TBCTL.bit.PHSEN = 0x0; EPwm3Regs.TBCTL.bit.CTRMODE = 0x0; } 模块的初始化 1、注意TBxxx的寄存器控制的是ePWM模块的时钟源,还有外部事件发生的载入计数值以及周期寄存器值,这里我只指出常用的寄存器。这里要根据自己的主频来,我用的是推荐的最高主频150MHz,还有一点要注意的是在UpCount和DownCount的计数方式下PWM周期为(TBPRD+1)*Ttbclk //3.125MHz.//period 62500.//1ms-》3125.//2ms-》6250 这里自己一定要算清楚,以上几个数据分别是在150MHz主频下此代码产生的1/Ttbclk、周期寄存器值、1ms对应的CMP寄存器值和2ms对应的CMP寄存器值。 2、CMPxxx控制的是与CTR计数器作比较的寄存器值,还有几个控制寄存器。其中需要注意的是dsp的pwm和其他mcu一样为了保护周期信号的完整性采用的缓冲格式,具体的是它成为“shadow”的一种模式,可以使能,也可以不使能。因为控制的是舵机,必须保证信号的周期是完整的20ms,所以选择shadow模式。主要是CMP比较寄存器值的shadow模式,因为周期Period寄存器20ms是固定不变的,设置不设置的无所谓了。 3、AQCTLA和AQCTLB寄存器主要控制的是事件发生时的电平变化情况,这两个寄存器根据自己的需要可以有很多不同的配制方法,是产生电平变化主要要配置的。PWMxA和PWMxB之间使用共同的PRD、CMPA、CMPB以及一些外部事件,这里我不需要那么复杂,只需要两路PWM既可以。 4、剩下几个模块有死区延迟、斩波处理pwm、强制转换电平、pwm中断几种,根据自己的需要再去看吧,控制舵机是完全用不上了。修改占空比只需要 EPwm3Regs.CMPA.half.CMPA = 6250; EPwm3Regs.CMPB=3125; 改变这两个寄存器。至于为什么CMPA的寄存器和CMP不同,看看底层就明白了,因为CMPA是32位的,其中还有16位是用来组合在HRPWM模块中使用的。

  • 发表了主题帖: DSP开发板的芯片中28335和2812哪块比较适合初学者?

        学习DSP就是从资料和例程开始,如果装了TI的ducontrolSUITE并且英语稍微过关的zhi话,里面的资料和例dao程都够初学者学习任意一种芯片。而这两块芯片相较而言2812有更多的中文资料可以参考,也有更多的其它学习者自己开发的程序参考,但28335技术更靠前一些,毕竟浮点DSP是以后的发展方向,其学习板和配套程序也已经成熟,从28335开始个人感觉要更好。   区别一: 28335数字bai信号处理器:         TMS320F28335数字信号处理器是duTI公司最新推出的32位浮点zhiDSP控制器。与TMS320F2812定点DSP相比,TMS320F28335增加了单精度浮点运算单元(FPU)和高精度PWM,且Flash增加了一倍(256K×16Bit)。 同时增加了DMA功能,可将ADC转换结果直接存入DSP的任一存储空间。此外,它还增加了CAN通讯模块、SCI接口和SPI接口。TMS320F28355的主频最高为150MHz,同时具有外部存储扩展接口、看门狗、三个定时器、18个PWM输出和16通道的12位AD转换器。 区别二: 2、28335的配置:         F28335拥有类似2812的XINTF(External Interface外部接口),但其功能更为强大,是16/32位数据位宽可配置,DMA可控制的。         在系统设计时,可以通过该接口很方便地扩展片外存储器和其他外设,独立设置它们的控制时这对于现在电力电子变流装置的控制十分重要。 因为片上外设往往并不能满足系统全部的控制要求,这就需要系统具有良好的可扩展性。F28335的可扩展性相比F2808上了一个台阶。 区别三: 3、28335和2812系列:         28335和2812同属C2000系列,最大不同是28335硬件支持浮点运算,处理浮点数性能优越。同时PWM、eCAP、eQEP尤其是PWM每一路都可以单独控制。         最主要的是定浮点,283XX或者2803X都是浮点芯片,28XX都是定点的,其他的功能模块总线什么的C2000大同小异,连寄存器配置都差不多。 扩展资料: 28335和2812的特点:         TMS320F28335具有150MHz的高速处理能力,具备32位浮 点处理单元,6个DMA通道支持ADC、McBSP和 EMIF,有多大18路的PWM输出,其中有6路为TI特有的更高精度的PWM输出 (HRPWM),12位16通道ADC。 得益于其浮点运算单元,用户可快速编写控制算法而无需再处理小数操作上耗费过多的时间和精力,与前代DSP相比,平均性能提高50%,并与定点C28x控制器软件兼容,从而简化软件开发, 缩短开发周期,降低开发成本。 DSP2812的特点:         TMS320F2812是基于代码兼容的C28x内核的新型高性能32位定点数字信号处理器,其代码与F24x/LF240x系列DSP代码及部分功能相兼容,C28x内核的指令执行周期达到了6.67ns,最高运行频率可以达到150MHz,保证了控制系统有足够的运算能力。 此外,F2812集成有许多外设,提供了整套的片上系统,从降低了系统成本,实现更简单、高效地控制。其片上外设主要包括2×8路12位ADC(最快80ns转换时间),2路SCI,1路SPI,1路McBSP,1路eCAN接口等。 并带有两个事件管理模块(EVA、EVB),分别包括6路PWM/CMP,2路QEP,3路CAP,2路16位定时器(或TxPWM/TxCMP)。另外,该器件还有3个独立的32位CPU定时器,以及多达56个独立编程的GPIO引脚。 由此可见,F2812在具备数字信号处理器卓越的数据处理能力的同时,又具有适于控制的片内外设及接口,可广泛应用于各种高性能的系统控制中。F2812不同于F24xx系列DSP,它采用统一编址方式。 芯片内部有18K的SARAM,包括MO、M1、L0、L1、H0共5个存储块。各存储块保持独立,可以在同一机器周期对不同的RAM块进行访问,从而减少流水线时延。而且F2812内部有128K字的FLASH,地址空间3D8000h~3F7FFFh,适用于低功耗、高性能的控制系统。         此外F2812提供了外部存储器扩展接口(XINTF),方便进行系统扩展,其寻址空间可以达到1MB。F2812有多种上电引导方式可供选择,可以通过设置GPIOF4、GPIOF12、GPIOF3、GPIOF2得不同状态进行DSP上电时的程序引导控制。

  • 发表了主题帖: TI的DSP2812与28335有什么区别

    2812不如28335新,bai示例程序少于不断增加和更新的28335; 2812是定点器du件,zhi28335是浮点器件,可单时钟完成一次浮点运算;dao 2812可扩展外存寻址范围是1M16bit,而28335是2M16bit; 2812的Flash和RAM均比较小; 2812的ADC有“硬伤”,精度不高,28335修正了这一设计错误; 28335的pwm输出有6通道的HRPWM可达到150ps的分辨率,2812的pwm精度较差; 最后,2812由于在用量上不如28335,价格会比后者高。 另外28335可以由定点的28035替代使用,除浮点部分均兼容,28035更便宜,价格有优势。

  • 2020-08-07
  • 发表了主题帖: ISO 26262 之故障容错时间间隔

    给大家分享的是功能安全里面又一个重要的概念——故障容错时间间隔(FTTI)。 故障容错时间间隔在ISO 26262中是一个很核心的概念,也可以称其为可靠性设计的核心概念。故障容错时间间隔是一个必须满足的安全需求。那么,什么是故障容错时间间隔呢?首先,我们来看一下标准中的定义。 Fault Tolerance Time Interval (FTTI) 故障容错时间间隔(FTTI) Minimum time-span from the occurrence of a fault in an item to apossible occurrence of a hazardous event, if the safety mechanisms are not activated. 在安全机制未被激活的情况下,从相关项内部故障发生到可能发生危害事件的最短时间间隔。 如上图,在系统正常运行的时候,突然发生故障,系统的安全机制检测到此故障后,系统会被置入安全状态。从故障发生到系统进入到安全状态这段时间就是我们所谓的FTTI。比如,电池充电过程中发生过流故障,到BMS检测到过流故障并且将电池置入安全状态(切断继电器,停止充电)的时间即为FTTI。 这里我们稍微提一下FTTI在标准中的注释第五条:The occurrence of a hazardous event is dependent on a fault being present and a vehicle being in a scenariothat allows the fault to affect vehicle behavior(危害事件的发生取决于存在的故障并且车辆处于故障可影响车辆行为的场景中)。这也就是说,通常我们在Concept阶段就必须根据安全目标所处的具体场景,具体事故的情况下定义FTTI。 此外关于时间间隔的定义,第二版的标准里也列的很明确,下面是简单的介绍: Fault Detection Time Interval (FDTI): Time-span from the occurrence ofa fault to its detection. 故障探测时间间隔: 从故障发生到检测的时间间隔。(见上图) Fault Reaction Time Interval (FRTI): Time-span from the detection ofa fault to reaching a safe state or to reaching emergency operation. 故障响应时间间隔: 从故障探测到进入到安全状态或者进入到紧急运行模式的时间间隔。(见上图) Fault Handling Time Interval (FHDI): Sum of fault detection timeinterval and the fault reaction time interval. 故障处理时间间隔: 故障检测时间间隔和故障响应时间间隔之和。(FHTI反应的是安全机制的属性) 以上,就是本期给大家分享的关于FTTI的基本知识。

  • 发表了主题帖: 基于波形捕获、用于超声波检测的方法

    MSP430 超声波检测 SoC 有助于实现独特的基于波形捕获的技术,其中针对上游和下游条件在时域中捕获传感器的整个响应。对这些波形进行后处理可确定差分飞行时间 (TOF)。   波形方法的优点 针对信号幅度变化(传感器/传感器变化、不同材料成分、高流速、噪声、温度变化等)具有很高的鲁棒性 提供泄漏检测,并且在低流速下具有极高的精度 具有噪声抑制功能,从而实现更高的精度并减小变化 使用标准 MCU 电压电平针对传感器提供 3V 的驱动能力 能够扩展,以进行材料和成分分析 随时间的推移进行仪表诊断的附加功能: 检测由于传感器老化而引起的包络缓慢变化,调节传感器/传感器谐振频率变化 消除产品使用寿命期间的定期校准

  • 发表了主题帖: MSP430™ 超声波检测微控制器

    MSP430™ 超声波检测微控制器,用于水表、燃气表和热量计的超低功耗 SoC,片上系统 MSP430™ 超声波检测 MCU 专为高精度的水、热量和燃气流量测量应用而设计。这些 MCU 具有超声波检测模拟前端等集成外设和 DSP 功能,且所有 MCU 均具有实时时钟、LCD 驱动器、12 位 SAR ADC 和比较器。 开始开发超声波水表 我们的 MSP430 超声波水计量开发环境旨在让您尽快安装和运行。 要开始使用,请执行以下步骤: 评估我们的高性能、低功耗水表参考设计 购买 EVM 下载 EVM 快速入门指南 下载我们的水计量软件并观看 演示 有关定制设计的问题,请参考我们的常见问题解答(FAQ) 文档。  有关超声波检测技术的更多背景信息,请阅读我们的波形捕获或观看我们的视频培训系列。 开始开发超声波燃气表 我们的 MSP430 超声波燃气计量开发环境旨在让您尽快安装和运行。 要开始使用,请执行以下步骤: 评估我们的高性能、成本优化型燃气表参考设计 购买 EVM 下载 EVM 快速入门指南 下载我们的燃气计量软件并观看演示

  • 发表了主题帖: msp430g2553的adc采样精度问题

    问题:用官方例程进行ad采样发现直流采样值非常抖,只有百位上数值不抖。 解决:1,ad采样须考虑采样基准电压稳不稳,对于2553来说,其基准电压可以设置为内部1.5v,2.5v,vcc。或者外部基准电压(0-vcc)。 2,采样频率,一般来说极高采样频率与极高准确度不可兼得。采样频率太高很可能造成电容的充电未满,对于2553只有两个采样频率50k,200k,都不算很高。对精度基本没影响。 3,采样保持时间,采样保持时间过长,电容的电荷流失得越多造成采样不准。所以采样保持时间必须得找到合适的值。对于2553采样的保持时间是与adc时钟有关的,所以adc时钟分频和采样保持时间须得联合考虑(一度只改了采样保持时间,没注意这个值与时钟得关系)。 4,采样源输出电阻大小,输出电阻太高会直接拉低采样值。最好加电压跟随器。 BCSCTL1=CALBC1_1MHZ; DCOCTL=CALDCO_1MHZ;   ADC10CTL1= INCH_4+ADC10DIV_0; ADC10CTL0=ADC10SHT_0+ADC10ON+ADC10IE+ADC10SR+REFON+SREF_1+REF2_5V;

  • 2020-08-06
  • 发表了主题帖: TI MSP430 如何实现模拟串口通信

    1、背景: 很多时候由于硬件资源有限,但又需要使用串口通信,此时可以考虑使用模拟串口; 2、前提: 要实现特定bps的串口速率,需要相应频率的定时器,保证误码率在可以接受的范围内; 例如: 1MHz的时钟最高可模拟9600bps的通信速率:1M/9600 = 104  误码率<1% 3、参考代码: //****************************************************************************** //  ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO //  //* An external watch crystal is required on XIN XOUT for ACLK *//   // //               MSP430G2xx1 //            ----------------- //        /|\|              XIN|- //         | |                 | 32kHz //         --|RST          XOUT|- //           |                 | //           |   CCI0B/TXD/P1.1|--------> //           |                 | 9600 8N1 //           |   CCI0A/RXD/P1.2|<-------- // //****************************************************************************** #include <msp430.h> //------------------------------------------------------------------------------ // Hardware-related definitions //------------------------------------------------------------------------------ #define UART_TXD   0x02                     // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD   0x04                     // RXD on P1.2 (Timer0_A.CCI1A) //------------------------------------------------------------------------------ // Conditions for 9600 Baud SW UART, SMCLK = 1MHz //------------------------------------------------------------------------------ #define UART_TBIT_DIV_2     (1000000 / (9600 * 2)) #define UART_TBIT           (1000000 / 9600) //------------------------------------------------------------------------------ // Global variables used for full-duplex UART communication //------------------------------------------------------------------------------ unsigned int txData;                        // UART internal variable for TX unsigned char rxBuffer;                     // Received UART character //------------------------------------------------------------------------------ // Function prototypes //------------------------------------------------------------------------------ void TimerA_UART_init(void); void TimerA_UART_tx(unsigned char byte); void TimerA_UART_print(char *string); //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ int main(void) {     WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer     if (CALBC1_1MHZ==0xFF)                                        // If calibration constants erased     {                                                                                              while(1);                             // do not load, trap CPU!!            }     DCOCTL = 0;                             // Select lowest DCOx and MODx settings     BCSCTL1 = CALBC1_1MHZ;     DCOCTL = CALDCO_1MHZ;     P1OUT = 0x00;                           // Initialize all GPIO     P1SEL = UART_TXD + UART_RXD;            // Timer function for TXD/RXD pins     P1DIR = 0xFF & ~UART_RXD;               // Set all pins but RXD to output     P2OUT = 0x00;     P2SEL = 0x00;     P2DIR = 0xFF;     __enable_interrupt();     TimerA_UART_init();                     // Start Timer_A UART     TimerA_UART_print("G2xx1 TimerA UART\r\n");     TimerA_UART_print("READY.\r\n");     for (;;)     {         // Wait for incoming character         __bis_SR_register(LPM0_bits);         // Update board outputs according to received byte         if (rxBuffer & 0x01) P1OUT |= 0x01; else P1OUT &= ~0x01;    // P1.0         if (rxBuffer & 0x02) P1OUT |= 0x08; else P1OUT &= ~0x08;    // P1.3         if (rxBuffer & 0x04) P1OUT |= 0x10; else P1OUT &= ~0x10;    // P1.4         if (rxBuffer & 0x08) P1OUT |= 0x20; else P1OUT &= ~0x20;    // P1.5         if (rxBuffer & 0x10) P1OUT |= 0x40; else P1OUT &= ~0x40;    // P1.6         if (rxBuffer & 0x20) P1OUT |= 0x80; else P1OUT &= ~0x80;    // P1.7         if (rxBuffer & 0x40) P2OUT |= 0x40; else P2OUT &= ~0x40;    // P2.6         if (rxBuffer & 0x80) P2OUT |= 0x80; else P2OUT &= ~0x80;    // P2.7         // Echo received character         TimerA_UART_tx(rxBuffer);     } } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) {     TACCTL0 = OUT;                          // Set TXD Idle as Mark = '1'     TACCTL1 = SCS + CM1 + CAP + CCIE;       // Sync, Neg Edge, Capture, Int     TACTL = TASSEL_2 + MC_2;                // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) {     while (TACCTL0 & CCIE);                 // Ensure last char got TX'd     TACCR0 = TAR;                           // Current state of TA counter     TACCR0 += UART_TBIT;                    // One bit time till first bit     TACCTL0 = OUTMOD0 + CCIE;               // Set TXD on EQU0, Int     txData = byte;                          // Load global variable     txData |= 0x100;                        // Add mark stop bit to TXData     txData <<= 1;                           // Add space start bit } //------------------------------------------------------------------------------ // Prints a string over using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_print(char *string) {     while (*string) {         TimerA_UART_tx(*string++);     } } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A0_ISR(void) {     static unsigned char txBitCnt = 10;     TACCR0 += UART_TBIT;                    // Add Offset to CCRx     if (txBitCnt == 0) {                    // All bits TXed?         TACCTL0 &= ~CCIE;                   // All bits TXed, disable interrupt         txBitCnt = 10;                      // Re-load bit counter     }     else {         if (txData & 0x01) {           TACCTL0 &= ~OUTMOD2;              // TX Mark '1'         }         else {           TACCTL0 |= OUTMOD2;               // TX Space '0'         }         txData >>= 1;         txBitCnt--;     } }       //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) {     static unsigned char rxBitCnt = 8;     static unsigned char rxData = 0;     switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching         case TAIV_TACCR1:                        // TACCR1 CCIFG - UART RX             TACCR1 += UART_TBIT;                 // Add Offset to CCRx             if (TACCTL1 & CAP) {                 // Capture mode = start bit edge                 TACCTL1 &= ~CAP;                 // Switch capture to compare mode                 TACCR1 += UART_TBIT_DIV_2;       // Point CCRx to middle of D0             }             else {                 rxData >>= 1;                 if (TACCTL1 & SCCI) {            // Get bit waiting in receive latch                     rxData |= 0x80;                 }                 rxBitCnt--;                 if (rxBitCnt == 0) {             // All bits RXed?                     rxBuffer = rxData;           // Store in global variable                     rxBitCnt = 8;                // Re-load bit counter                     TACCTL1 |= CAP;              // Switch compare to capture mode                     __bic_SR_register_on_exit(LPM0_bits);  // Clear LPM0 bits from 0(SR)                 }             }             break;     } } //------------------------------------------------------------------------------

  • 发表了主题帖: 分享初学者学习430单片机的一些方法

    其实单片机的内容本身就非常丰富,而且实用性和实践性都很好;并且单片机学习可以有效的提高学习者的动手能力,从而,为进一步学习嵌入式打下基础。   在TI官网上找到MSP430的程序例程、数据手册、使用指南等文件。以MSP430F169为例,步骤如下: 1)进入ti官网:http://www.ti.com.cn/ 或者http://www.ti.com.cn/sitesearch/cn/docs/universalsearch.tsp?searchTerm=msp430f169#linkId=1&src=top 2)在所有搜索栏填入:msp430f169点击搜索 3)可以根据需要下载芯片数据手册(datasheet)、模块使用指南(user guide)、官方的程序范例程序(code example for msp4301**)等,建议把MSP430F169.h文件也读下; 你懂的,所有文件外加其他库和演示文件。链接: https://pan.baidu.com/s/1dFaqWDz 密码: y9vm 4)点击对应的链接下载文件即可; 5)既可以开始学习MSP430单片机了。

统计信息

已有583人来访过

  • 芯币:5843
  • 好友:--
  • 主题:1709
  • 回复:108
  • 课时:--
  • 资源:--

留言

你需要登录后才可以留言 登录 | 注册


Mr-kk 2020-5-26
你好,我是一名学生,看了你的F2812DSP的最小系统设计这篇文章,想请问一下您有没有pcb相关的文件可以分享的嘛,非常感谢
查看全部