历史上的今天
返回首页

历史上的今天

今天是:2025年03月25日(星期二)

正在发生

2020年03月25日 | 基于CCS工程MSP430串口升级(一)

2020-03-25 来源:eefocus

第一次接触MSP430的芯片,第一次使用CCS开发环境,花了将近一个星期的时间,才把MSP430串口升级做出来。


同样分成BOOT,APP,上位机,三个部分来讲解。


BOOT

在lnk_msp430fg479.cmd中修改BOOT Flash的起始地址(0xF000~0xFFE0),将近4K的Flash

MEMORY

{

    SFR                     : origin = 0x0000, length = 0x0010

    PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0

    PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100

    RAM                     : origin = 0x0200, length = 0x0800

    INFOA                   : origin = 0x10C0, length = 0x0040

    INFOB                   : origin = 0x1080, length = 0x0040

    INFOC                   : origin = 0x1040, length = 0x0040

    INFOD                   : origin = 0x1000, length = 0x0040

//    FLASH                   : origin = 0x1100, length = 0xEEE0 

    FLASH                   : origin = 0xF000, length = 0x0FE0

    INT00                   : origin = 0xFFE0, length = 0x0002

    INT01                   : origin = 0xFFE2, length = 0x0002

    INT02                   : origin = 0xFFE4, length = 0x0002

    INT03                   : origin = 0xFFE6, length = 0x0002

    INT04                   : origin = 0xFFE8, length = 0x0002

    INT05                   : origin = 0xFFEA, length = 0x0002

    INT06                   : origin = 0xFFEC, length = 0x0002

    INT07                   : origin = 0xFFEE, length = 0x0002

    INT08                   : origin = 0xFFF0, length = 0x0002

    INT09                   : origin = 0xFFF2, length = 0x0002

    INT10                   : origin = 0xFFF4, length = 0x0002

    INT11                   : origin = 0xFFF6, length = 0x0002

    INT12                   : origin = 0xFFF8, length = 0x0002

    INT13                   : origin = 0xFFFA, length = 0x0002

    INT14                   : origin = 0xFFFC, length = 0x0002

    RESET                   : origin = 0xFFFE, length = 0x0002

}


中断向量重映射,BOOT中断函数跳转到APP中断函数

// Timer A0 interrupt service routine

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)

#pragma vector=TIMERA0_VECTOR

__interrupt void Timer_A (void)

#elif defined(__GNUC__)

void __attribute__ ((interrupt(TIMERA0_VECTOR))) Timer_A (void)

#else

#error Compiler not supported!

#endif

{

asm(" br &0xEFEC;");

}


#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)

#pragma vector=SD16A_VECTOR

__interrupt void SD16ISR(void)

#elif defined(__GNUC__)

void __attribute__ ((interrupt(SD16A_VECTOR))) SD16ISR (void)

#else

#error Compiler not supported!

#endif

{

asm(" br &0xEFEE;");

}


// Watchdog Timer interrupt service routine

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)

#pragma vector=WDT_VECTOR

__interrupt void watchdog_timer(void)

#elif defined(__GNUC__)

void __attribute__ ((interrupt(WDT_VECTOR))) watchdog_timer (void)

#else

#error Compiler not supported!

#endif

{

asm(" br &0xEFF4;");

}


#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)

#pragma vector=USCIAB0RX_VECTOR

__interrupt void USCI_A0_rx (void)

#elif defined(__GNUC__)

void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) USCI_A0_rx (void)

#else

#error Compiler not supported!

#endif

{

// printf("%c",UCA0RXBUF);

// if(isBoot==2)

// {

// u16 rxAddr = 0xBFF2  ;

// ((void (*)(void))appAddr)();

asm(" br &0xEFF2;");

// }

// else

// {

// rx_buf[rx_buf_index++] = UCA0RXBUF;

// if(rx_buf_index>=RX_SIZE)

// rx_buf_index = 0;

// }

}


这边需要注意的一点是,APP和BOOT的中断函数不要有冲突,有重复。比如APP有串口接收中断,BOOT就不能有串口接收中断。至于为什么,后面再解释。在这里,APP的内容比较多,必须要有串口接收中断提高实时性,那就只能委屈BOOT轮询串口缓冲。


while(1)

{

// delay_ms(1000);

for(i=0;i<0x7fff;i++)

{

if(IFG2&UCA0RXIFG)

{

i=0;

rx_buf[rx_buf_index++] = UCA0RXBUF;

if(rx_buf_index>=RX_SIZE)

rx_buf_index = 0;

}

}


if(rx_buf_index > 5)

{

if(rx_buf[0]==MODBUS_DO)

{

crc = CRC16(rx_buf, rx_buf_index-2);

if(crc == ((rx_buf[rx_buf_index-1]<<8)|rx_buf[rx_buf_index-2]))

{

switch(rx_buf[1])

{

case 0x03:

Modbus_Function_3();

break;

case 0x10:

Modbus_Function_10();

break;

case 0x45:

Modbus_Function_45();

break;

}

}

}

rx_buf_index = 0;

}

}


Flash读写,MSP430FG479这款MCU,一个片区512字节,所以需要整片512字节的擦除写入。每次写入前,先把该片区的512字节读取到缓存中,再将需要修改的内容填充到缓存中,最后一次将512字节写入Flash片区

在这里插入图片描述

void Flash_SecureWrite(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)

{

int i=0;

u16 offsetAddr = WriteAddr%512;

u16 baseAddr = WriteAddr-offsetAddr;

FLASH_Read(baseAddr, tx_buf, 512);

for(i=0; i {

tx_buf[offsetAddr+i] = pBuffer[i];

}

FLASH_Write(baseAddr, tx_buf, 512);

}


void FLASH_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)

{

char *Flash_ptr;                          // Flash pointer

unsigned int i;


Flash_ptr = (char *)WriteAddr;            // Initialize Flash pointer

FCTL3 = FWKEY;                            // Clear Lock bit

FCTL1 = FWKEY + ERASE;                    // Set Erase bit

*Flash_ptr = 0;                           // Dummy write to erase Flash seg


FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation


for (i = 0; i < NumToWrite; i++)

{

  *Flash_ptr++ = pBuffer[i];                   // Write value to flash

}


FCTL1 = FWKEY;                            // Clear WRT bit

FCTL3 = FWKEY + LOCK;                     // Set LOCK bit

}


void FLASH_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)

{

char *Flash_ptr;

u32 i;

Flash_ptr = (char *)ReadAddr;            // Initialize Flash pointer


for(i=0; i pBuffer[i] = *Flash_ptr++;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

拷贝结束后,BOOT跳转到APP。

void Boot2App(void)

{

// u16 appAddr = 0xBFFE  ;// 0x1200

FLASH_Read(PROJECT_VERSION_ADDR,(u8 *)projectVersion,0x10);

FLASH_Read(FLASH_OTA_STATUS_ADDR,(u8 *)&isBoot,2);//App(0) or Boot(1)


if(isBoot==0)

{

if(strstr(projectVersion,"AquaDO"))

{

isBoot = 2;

delay_ms(1000);

rs485_send("Boot2Apprn",strlen("Boot2Apprn"));

asm(" mov &0xEFFE,PC;");

// asm(" mov #0xBFFE,PC;");

// asm(" mov #0x1200,PC;");

// asm(" br &0x1200;");

// asm(" LB 0x1200");

// ((void (*)(void))appAddr)();

}

}

}

推荐阅读

史海拾趣

ABI Electronics公司的发展小趣事

随着业务的不断发展和产品的不断升级,ABI Electronics公司的品牌影响力也逐渐提升。其产品在市场上获得了良好的口碑和声誉,成为了电子行业内的知名品牌。同时,ABI还积极参与行业内的交流和合作,为行业的发展做出了积极的贡献,进一步提升了其在行业内的地位和影响力。

这五个故事展示了ABI Electronics公司在电子行业里的发展历程,从电路板测试技术的突破,到集成电路测试技术的创新,再到全球市场布局和合作伙伴关系的建立,以及研发实力的持续增强和品牌影响力的提升,都体现了ABI Electronics公司不断进取、不断创新的精神。

珠海艾派克(APEXMIC)公司的发展小趣事

随着技术的不断进步,艾派克逐渐在打印机芯片领域取得了突破。公司成功研发出一系列从打印机主控SoC芯片到耗材加密芯片的全系列打印机芯片产品,不仅满足了国内市场的需求,还成功打入国际市场,成为全球打印机通用耗材芯片的重要供应商。这一成就标志着艾派克在打印机芯片领域的领先地位得到了进一步巩固。

Fermionics Lasertech Inc公司的发展小趣事

随着技术的不断完善,Fermionics Lasertech Inc公司的产品线逐渐丰富,从单一的激光切割设备扩展到激光打标、焊接、打孔等多个领域。公司开始加大市场推广力度,积极参加国内外各类电子展会,与潜在客户建立联系。同时,公司还注重品牌建设,通过优质的产品和服务赢得了良好的口碑,逐渐在电子行业树立了品牌形象。

Faraday Technology公司的发展小趣事

作为一家有社会责任感的企业,Fermionics Lasertech Inc公司始终关注环境保护和社会公益事业。他们积极推行绿色制造理念,采用环保材料和节能技术生产产品;同时,公司还积极参与各类公益活动,回馈社会。这些举措不仅提升了公司的社会形象,也为公司的可持续发展注入了强大动力。

ALD [Advanced Linear Devices]公司的发展小趣事

面对日益激烈的市场竞争,Fermionics Lasertech Inc公司始终坚持以创新为驱动力。他们不断投入研发资金,引进高端人才,加强与高校和科研机构的合作,共同推动激光技术的创新。公司成功研发出了一系列具有自主知识产权的新型激光器,不仅提升了产品性能,还降低了生产成本,使公司在激烈的市场竞争中保持领先地位。

扬州国芯(Gcore)公司的发展小趣事

随着公司规模的不断扩大,Fermionics Lasertech Inc公司开始寻求国际合作与全球布局。他们与国外的知名企业和研究机构建立了紧密的合作关系,共同开展技术研发和市场拓展。同时,公司还在海外设立了多个分支机构和办事处,以便更好地服务当地客户。这些举措不仅提升了公司的国际影响力,还为公司的长期发展提供了有力保障。

问答坊 | AI 解惑

时间触发嵌入式系统设计模式:使用8051微控制器开发可靠应用(含光盘源代码下载)

时间触发嵌入式系统设计模式:使用8051微控制器开发可靠应用(含光盘源代码下载) 目录: 第1章 什么是时间触发的嵌入式系统 1.1 引言 1.2 信息系统 1.3 桌面系统 1.4 实时系统 1.5 嵌入式系统 1.6 事件触发系统 1.7 时间触发系统 1.8 小结 ...…

查看全部问答>

哪位知道ADC采样需要通过软件系数标定处理?

寻求算法,最好可以举例。 谢谢了!!!…

查看全部问答>

关于二维数组指针

在Keil中使用二维数组指针时总是提示语法错误,但我用DEV-C++建立的C工程上却正常. 是Keil编译器不支持二维数组指针吗?有没有什么办法来解决? unsigned char (* PY_index_pointer[27])[8]={              &nbs ...…

查看全部问答>

有个问题

我申请做一个可以进行51、avr、arm实验的大学生单片机实验平台,想命名为“单片机与嵌入式综合实验平台”,不知道好不好,请各位提提建议。 注:有的说嵌入式包括了单片机…

查看全部问答>

2011造什么?造飞碟

如果我说造飞碟,你认为是天方夜谭那么我告诉你,你落后了。在网上有几千UFO研究者和制造者!以下是关于飞碟制造的资料和设计参考!!! 瑟尔效应反重力研究群: 永动机: 分别介绍我所有的资料: 1、纳粹德国飞碟制造:  &n ...…

查看全部问答>

对于每日一问的建议

论坛里开的这个每日一问真的很不错,不管对于哪个层次的来说都很有好处,个人建议下提过问题以后,能不能对每个问题做一个总结,这个总结不一定要是结果,而且是解决问题的方法和思路。 不好意思我现在只能对我们初学者提点建议,有说错话的地方请 ...…

查看全部问答>

speic电路问题,计算和仿真都可以但就是做出来有问题,请教大家啦!!

按照speic电路模型,计算出L1=L2=100uH,(用工字电感)。Cs是用22uF的极性电容,mos管用IRF540N,pwm 20k,输出电容为104和10uF的极性电容,负载280欧,二极管用IN5822肖特基二极管,输入用5v但无论怎么改变占空比输出都是0.不知道什么原因…

查看全部问答>

运算放大器电路的固有噪声分析与测量

运算放大器电路的固有噪声分析与测量,不错的资料:    …

查看全部问答>

DCO测试工程

这个工程可以测试DCO的4096个设置值所对应的频率值,并使用串口发送到上位机。测试平台是使用32KHz晶振的G2系列MSP430.横坐标是DCOCTL (DCOx, MODx)值纵坐标为频率值16条线为RSELx 值…

查看全部问答>

Beaglebone开发环境的搭建

1  装好Linux后,开启相应的服务及软件,包括:tftp,NFS,Samba,使用apt-get install安装即可。     安装ti-sdk-am335x-evm-05.03.02.00-Linux-x86-Install 后,可运行其中的setup.sh      装好后即设置交叉编 ...…

查看全部问答>