------------230303更新--------------------
经过这两天的测试,FLASH读数据异常问题可稳定复现,复现过程如下:
新建一个工程,新建关于FLASH操作的文件,包含两个函数:一个向指定地址写数据,一个读指定地址数据。
在main.c中,先向指定地址写数据01,然后读该地址数据,之后再向该地址写数据02,最后读该地址数据并打印输出。
理论上打印输出值应该为02,但实际打印输出值为01。
相关代码如下:
FLASH操作文件的两个函数:
void Flash_save(u16 dat) {
? ? FLASH_Unlock_Fast();
? ? FLASH_ErasePage_Fast(0x0800E080);
? ? FLASH_BufReset();
? ? FLASH_BufLoad(0x0800E080, dat, 0, 0, 0);
? ? FLASH_ProgramPage_Fast(0x0800E080);
? ? FLASH_Lock_Fast();
}
//读取指定地址的半字(16位数据)
uint16_t FLASH_ReadHalfWord(uint32_t address) {
? ? return *(__IO uint16_t*) address;
}
MAIN.C的相关代码:
int main(void) {
? ? GPIO_InitTypeDef GPIO_t;
? ? u16 n1, n2;
? ? NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
? ? Delay_Init();
? ? USART_Printf_Init(9600);
? ? //485设置为输出模式
? ? GPIO_t.GPIO_Mode = GPIO_Mode_Out_PP;
? ? GPIO_t.GPIO_Speed = GPIO_Speed_50MHz;
? ? GPIO_t.GPIO_Pin = GPIO_Pin_8;
? ? GPIO_Init(GPIOA, &GPIO_t);
? ? GPIO_SetBits(GPIOA, GPIO_Pin_8);
? ? printf("SystemClk:%d\r\n", SystemCoreClock);
? ? printf("This is printf example\r\n");
? ? n2 = 0;
? ? Flash_save(0x01);
? ? while(1)
? ? {
? ? ? ? if (n2 < 1000)
? ? ? ? {
? ? ? ? ? ? ++n2;
? ? ? ? ? ? printf("test flash save read\r\n");
? ? ? ? ? ? Delay_Ms(3000);
? ? ? ? ? ? //n1 = *(u16 *)(0x0800E080);
? ? ? ? ? ? n1 = FLASH_ReadHalfWord(0x0800e080);
? ? ? ? ? ? Flash_save(0x20);
? ? ? ? ? ? //n1 = *(u16 *)(0x0800E080);
? ? ? ? ? ? n1 = FLASH_ReadHalfWord(0x0800e080);
? ? ? ? ? ? printf("n1=:%d\r\n",n1);
? ? ? ? }
? ? }
}
--------------------------------------------以下是原问题描述----------------------------------------------------------
使用CH32V103C8T6,通过RS485通讯发送指令修改RS485通讯地址,写完数据之后马上读取以验证写数据是否成功,但读出的数据仍是写之前的旧的485地址。开始以为是写数据失败,但通过读地址指令读出来的地址又是更改后的地址,在OLED显示界面调取485地址,也是写后的新地址。
但是在处理485通讯的函数内,写完485地址,马上去读写入后的地址,读出来的却始终是原来的旧地址。
程序部分代码如下:
if (regValue[0] == 0 || regValue[0] > 247) //按协议,地址范围在1-247
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? Flash_Save_RS485ID(regValue[0]);
????????????//测试用,正式版删除
? ? ? ? ? ? tx_buf[2] = msg_t->rx_buf[2];
? ? ? ? ? ? tx_buf[3] = msg_t->rx_buf[3];
? ? ? ? ? ? regValue[1] = FLASH_ReadHalfWord(SIMD_RS485_BASE_ADDR);??
? ? ? ? ? ? tx_buf[4] = regValue[1]>>8;
? ? ? ? ? ? tx_buf[5] = regValue[1];
? ? ? ? ? ? RS485_SendData(tx_buf, 6);
? ? ? ? ? ? return;
????????????//验证写地址是否成功
? ? ? ? ? ? if (regValue[0] != *(u16 *) (SIMD_RS485_BASE_ADDR))
? ? ? ? ? ? ? ? return;
以上代码写数据是成功的,后续用读485地址指令可以正常读出更改后的新485地址,在OLED显示界面调出485地址也是新的地址。
但在写完后马上读数据以验证写入是否成功的时候,读出的数据却始终是旧的数据。