第1章 使用Sysconfig配置TMS320F283xx的SCI通信底层
1.1 为什么选择使用Sysconfig配置代码
我是自学的DSP芯片,用过TMS320F28335,TMS320F28377,之前学习时使用的都是寄存器开发,感觉写代码时对底层的配置非常清晰,但是效率太低,代码底层也比较臃肿,当时就想有没有像STM32那样有标准库最好是HAL库开发,后来才知道是有的,就是sysconfig这个图形化编程工具来配置底层代码,类似STM32中的HAL库开发,更牛的地方是sysconfig芯片配置出的代码是标准库,但是在使用过程中多少会发生一些BUG,现在TI正在慢慢完善这个工具,相信后面会更加好用。本例程使用的是TMS320F28388D来配置SCI。
1.2 使用sysconfig配置SCI
我使用的是CPU1控制用来做SCI通信,有感兴趣的小伙伴试试能不能使用CPU2来控制,手册中说要先使用CPU1来分配资源给CPU2,目前我还没有尝试,欢迎有能够实现的小伙伴分享出方法,废话不多说,直接上操作步骤以及代码解释。
配置SCI通信代码:

注意:一定要检查时钟的配置是否合适,建议使用上图的配置,时钟太快会导致数据传输不正确,时钟配置可在图中左上方第二个标的时钟树中改变。
我使用的是RS485,之前看到一篇文章说RS485的波特率最好不要超过115200,否则数据会发生错乱,这里波特率就选测了115200,可以看出是有误差的,但是我打算使用Modbus RTU协议,能够识别发送数据是否正确,这点误差还是可以接收的,我配置的接收和发送FIFO只有一个数据,是因为Modbus协议数据长度不确定,所以打算一次只接受一位数据,不至于卡在FIFO等待接收数据,若每次发送和接收的数据长度一定,建议还是使用FIFO。
配置完成后编译会报错,不然就是中断配置有问题。这是因为还没有写中断函数,但是sysconfig配置生成的board.h文件中声明了这个中断函数,下一章解决。
第2章 中断配置
2.1 中断向量表的配置以及PIE分组配置
在sysconfig配置完SCI后,就不用管PIE分组以及向量映射了,sysconfig已经帮我们配置好了,所以我们不用去管,只需要在主函数初始化的时候调用 Board_init();//初始化来自SysConfig的配置
main.c文件配置代码:
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "Interrupt.h"
void main(void)
{
Device_init();//初始化所有时钟以及外设
Interrupt_initModule();//初始化PIE,清除所有PIE寄存器,失能CPU中断
Interrupt_initVectorTable();//初始化PIE向量表
Board_init();//初始化来自SysConfig的配置
Device_bootCPU2(BOOT_MODE_CPU2);//启动CPU2核心部分
EINT;//使能全部中断
ERTM;//使能允许调试
while(1)
{
GPIO_togglePin(LED1);
DEVICE_DELAY_US(1000000);
}
}
2.2 中断函数
中断函数代码为:
uint16_t
__interrupt void INT_RS485_RX_ISR(void)
{
SCI_readCharArray(RS485_BASE, &receivedData, 1);
// Modbus_zubao(receivedData);
SCI_clearOverflowStatus(RS485_BASE);
SCI_clearInterruptStatus(RS485_BASE, SCI_INT_RXFF);
Interrupt_clearACKGroup(INT_RS485_RX_INTERRUPT_ACK_GROUP);
}
其中 SCI_readCharArray(RS485_BASE, &receivedData, 1);函数为接收数据函数,接收中断触发后通过该函数将数据读到receivedData中,由其他函数进行调用。
SCI_clearOverflowStatus(RS485_BASE);
SCI_clearInterruptStatus(RS485_BASE, SCI_INT_RXFF);
Interrupt_clearACKGroup(INT_RS485_RX_INTERRUPT_ACK_GROUP);
这三行代码解释为:
(1)清除覆盖标志位
(2)清除SCI的中断标志位
(3)清除中断分组标志位,PIE分组
第3章 printf函数的使用
在SCI使用过程中如果调用发送数据指令,代码为:
void Modbus_SendData(unsigned char *buff,unsigned char len)
{
unsigned char t;
TX_EN;
for(t=0;t<len;t++)
{
SCI_writeCharArray(RS485_BASE, (uint16_t*)&buff[t], 1);
DEVICE_DELAY_US(2000);//要与时钟对应
}
RX_EN;
}
感觉比较臃肿,而且发送数据种类有限,不方便调试使用,我比较喜欢使用printf函数发送数据,使用printf函数需要对SCI进行重映射。
3.1 使用printf但不进行重映射
代码为:
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "stdio.h"
#include "Interrupt.h"
//int fputc(int ch, FILE *f)
//{
// if (ch == '\n') {
// SCI_writeCharBlockingFIFO(RS485_BASE, '\r');
// }
// SCI_writeCharBlockingFIFO(RS485_BASE, (uint16_t)ch);
// return ch;
//}
void main(void)
{
Device_init();//初始化所有时钟以及外设
Interrupt_initModule();//初始化PIE,清除所有PIE寄存器,失能CPU中断
Interrupt_initVectorTable();//初始化PIE向量表
Board_init();//初始化来自SysConfig的配置
EINT;//使能全部中断
ERTM;//使能允许调试
while(1)
{
printf("hello!\r\n");
GPIO_togglePin(LED1);
DEVICE_DELAY_US(1000000);
}
}
现象为:
(1)监视框现象

(2)上位机现象

当在线运行时监视框会打印printf函数里面的内容但上位机接收不到信息。
3.2 使用printf并进行重映射
这部分操作步骤有些多,首先需要增加堆栈大小:
将堆栈改大一些:

适当就好,不用太大,这里设置为400,这时编译应该会报错说:
#10099-D program will not fit into available memory, or the section contains a call site that requires

最低0.47元/天 解锁文章
1308

被折叠的 条评论
为什么被折叠?



