在微控制器的ISR内,我试图按以下方式调用函数:
//adc.c
static volatile char uartBuf[6]={0};
CY_ISR(ISR_ADC)
{
for (uint8_t i=0; i < NS; i++)
total += adc2_buffer0[i];
uartBuf[0] = total >> 24 & 0xFF;
uartBuf[1] = total >> 16 & 0xFF;
uartBuf[2] = total >> 8 & 0xFF;
uartBuf[3] = total & 0xFF;
uartBuf[4] = '\n';
UART_1_PutString(uartBuf); //doesn't work
}
//uart.c
void UART_1_PutString(const char8 string[])
{
...
}
但是在函数UART_1_PutString中,字符串始终指向'\ 0'而不是uartBuf吗? 可能是什么问题呢?从理论上讲,变量uartBuf不应由编译器优化。
答案 0 :(得分:1)
代码似乎正确
您是说string[0] == '\0'
吗?
也许总是(total >> 24 & 0xFF) == 0
(或大部分时间)。
编辑:
该功能应该是
void UART_1_PutString(const volatile unsigned char buff[]);
不应将其称为字符串,因为它不是文本,它只是一个缓冲区(至少看起来像它)。
unsigned
,因为“字符串”来自一些数学运算后的无符号位操作,这可能会导致无效的有符号值(不太可能失败,但规则应为:char
用于文本, unsigned char
用于未知数据(其他所有数据)。
volatile
,因为如果没有,您将丢弃volatile
限定词。具有足够高的标志的编译器(在GCC:-Wall -Wextra -Werror
中会突出显示几乎所有内容,因为错误)会警告您。编译器可能认为,即使在知道您将使用volatile
数据调用该函数之前,该函数的内容也可以得到简化,因此可以优化一些不应该优化的内容。
如果没有其他函数同时访问该缓冲区,则还可以添加restrict
关键字(C11),以便帮助编译器生成更好的代码:
void UART_1_PutString(const volatile unsigned char buff[restrict]);
EDIT2:
如果仅将要使用该缓冲区的缓冲区,则应声明该缓冲区的大小;否则,请将该缓冲区的大小传递给函数:
void UART_1_PutString(const volatile unsigned char buff[restrict 6]);
(6可能应该用某个宏代替)或
void UART_1_PutString(size_t size, const volatile unsigned char buff[restrict size]);