[National Technology N32G457 Review] 11 N32G45 and STM32 CAN Communication Example
[Copy link]
This post was last edited by lugl4313820 on 2022-1-29 16:06
Yesterday, the communication between N32g45 and STM32F103VE was realized, [New reminder] [National Technology N32G457 evaluation] 10 RT_Thread Studio drives CAN and STM32F103VE communication - Domestic chip communication - Electronic Engineering World - Forum (eeworld.com.cn) . In addition, the key display of ssd1306 of N32G45 a few days ago, [New reminder] [National Technology N32G457 evaluation] 6 GPIO + I2C key interrupt + SSD1306 display - Domestic chip communication - Electronic Engineering World - Forum (eeworld.com.cn) .
Today, I realized the use of two buttons on the stm32F103VE development board to control the display of the ssd1306 of the N32G45.
The main idea is: when the stm32 key scans and finds that the key has changed, it sends data to the N32G45 through the can, and the status change bit is data[1]. After receiving the data, the N32G45 determines that the id and data[1] match the status and updates the display status. The N32G45 updates the oled display when it finds that the flag bit has changed through a thread.
The project files are attached for university participation. Of course, this is just a test project, just to achieve the function, and it is not very rigorous, so please forgive me.
The main code of stm32F103VE is as follows:
/* 左键中断回调函数 */
void disp_left(void *args)
{
rt_kprintf("but sw2\r\n");
flag_key = 0;
}
/* 右键中断回调函数 */
void disp_right(void *args)
{
rt_kprintf("but sw3\r\n");
flag_key = 1;
}
void init_Key(void)
{
/* 按键1引脚为输入模式 */
rt_pin_mode(SW2, PIN_MODE_INPUT_PULLUP);
/* 绑定中断,上升沿模式,回调函数名为beep_on */
rt_pin_attach_irq(SW2, PIN_IRQ_MODE_FALLING, disp_left, RT_NULL);
/* 使能中断 */
rt_pin_irq_enable(SW2, PIN_IRQ_ENABLE);
/* 按键1引脚为输入模式 */
rt_pin_mode(SW3, PIN_MODE_INPUT_PULLUP);
/* 绑定中断,上升沿模式,回调函数名为beep_on */
rt_pin_attach_irq(SW3, PIN_IRQ_MODE_FALLING, disp_right, RT_NULL);
/* 使能中断 */
rt_pin_irq_enable(SW3, PIN_IRQ_ENABLE);
}
void send_flag(void)
{
if(flag_key == 0 || flag_key == 1)
{
can1_send_sw_RTR(flag_key);
flag_key = 3;
}
}
void can1_send_sw_RTR(int sta)
{
struct rt_can_msg msg = {0};
msg.id = 0x123; /* ID 为 0x456 */
msg.ide = RT_CAN_STDID; /* 标准格式 */
msg.rtr = RT_CAN_RTR; /* 远程帧 */
msg.data[1] = sta;
int size = rt_device_write(can1_dev, 0, &msg, sizeof(msg));
if (size < 0)
{
rt_kprintf("can1 dev write data failed rc:%d\n",size);
}
}
The main code of N32G45V is as follows:
while(1)
{
/* hdr 值为 - 1,表示直接从 uselist 链表读取数据 */
rxmsg.hdr = -1;
/* 阻塞等待接收信号量 */
rt_sem_take(&can1_rx_sem, RT_WAITING_FOREVER);
/* 从 CAN 读取一帧数据 */
rt_device_read(can1_dev, 0, &rxmsg, sizeof(rxmsg));
rt_kprintf("CAN1 RX\n");
/* 打印数据 ID 及内容 */
if(rxmsg.rtr == RT_CAN_RTR) //远程帧
{
if(rxmsg.ide == RT_CAN_EXTID)//扩展帧
{
rt_kprintf("ID:0x%08X RTR len:%d \n", rxmsg.id, rxmsg.len);
}else
{
rt_kprintf("ID:0x%04X RTR len:%d \n", rxmsg.id, rxmsg.len);
}
if(rxmsg.id == 0x123)
{
//can1_send_0x123();
if(rxmsg.data[1] == 0)
{
flag_key = 0;//0表达左
}
else if (rxmsg.data[1] == 1) {
flag_key = 1;//1表示右
}
}
}else //数据帧
{
if(rxmsg.ide == RT_CAN_EXTID)//扩展帧
{
rt_kprintf("ID:0x%08X len:%d ", rxmsg.id, rxmsg.len);
for (int i = 0; i < rxmsg.len; i++)
{
rt_kprintf(" %02X", rxmsg.data);
}
rt_kprintf("\n");
}else
{
rt_kprintf("ID:0x%04X len:%d ", rxmsg.id, rxmsg.len);
for (int i = 0; i < rxmsg.len; i++)
{
rt_kprintf(" %02X", rxmsg.data);
}
rt_kprintf("\n");
//can1_send_0x123();
if(rxmsg.data[1] == 0)
{
flag_key = 0;//0表达左
}
else if (rxmsg.data[1] == 1) {
flag_key = 1;//0表达左
}
}
}
void disp_flag(void)
{
if (flag_key == 0) {
ssd1306_Fill(Black);
ssd1306_SetCursor(2,16);
ssd1306_WriteString("LEFT", Font_16x26, White);
ssd1306_UpdateScreen();
flag_key == 3;
}
else if (flag_key == 1) {
ssd1306_Fill(Black);
ssd1306_SetCursor(48,16);
ssd1306_WriteString("RIGHT", Font_16x26, White);
ssd1306_UpdateScreen();
flag_key == 3;
}
}
Finally, here is the video. Since the stm32 development board is not as easy to use as the N32G45, it is a bit difficult to press the buttons. Sorry for the joke!
|