lugl4313820 发表于 2022-1-29 15:55

【国民技术N32G457评测】十一 N32G45 与STM32 CAN通信实例

本帖最后由 lugl4313820 于 2022-1-29 16:06 编辑

<p>昨天实现了N32g45与STM32F103VE的通信,<a href="https://bbs.eeworld.com.cn/thread-1193235-1-1.html">【新提醒】【国民技术N32G457评测】十 RT_Thread Studio 驱动CAN 与STM32F103VE通讯 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a>。再加上前几天的N32G45的ssd1306的按键显示,<a href="https://bbs.eeworld.com.cn/thread-1193063-1-1.html">【新提醒】【国民技术N32G457评测】6 GPIO + I2C 按键中断+SSD1306显示 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a>。</p>

<p>今天实现了用stm32F103VE开发板上的两按按键控制N32G45的ssd1306的显示。</p>

<p>主要思路为:stm32按键扫描到按键有改变时通过can向N32G45发送数据,状态改变位为data。N32G45接收到数据后,判断id与data如果符合状态就更新显示状态。N32G45通过一个线程发现有标志位有改变就更新oled的显示。</p>

<p>附工程文件供大学参与。当然这只是测试工程,仅为实现功能而已,写得不是很严谨,望大家见谅。</p>

<p>stm32F103VE主要代码如下:</p>

<pre>
<code>/* 左键中断回调函数 */
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 = sta;
    int size = rt_device_write(can1_dev, 0, &amp;msg, sizeof(msg));
    if (size &lt; 0)
    {
      rt_kprintf("can1 dev write data failed rc:%d\n",size);
    }
}
</code></pre>

<p>N32G45V主要代码如下:</p>

<pre>
<code>while(1)
    {
            /* hdr 值为 - 1,表示直接从 uselist 链表读取数据 */
            rxmsg.hdr = -1;
            /* 阻塞等待接收信号量 */
            rt_sem_take(&amp;can1_rx_sem, RT_WAITING_FOREVER);
            /* 从 CAN 读取一帧数据 */
            rt_device_read(can1_dev, 0, &amp;rxmsg, sizeof(rxmsg));

            rt_kprintf(&quot;CAN1 RX\n&quot;);
            /* 打印数据 ID 及内容 */
            if(rxmsg.rtr == RT_CAN_RTR)//远程帧
            {
                if(rxmsg.ide == RT_CAN_EXTID)//扩展帧
                {
                  rt_kprintf(&quot;ID:0x%08X RTR len:%d \n&quot;, rxmsg.id, rxmsg.len);
                }else
                {
                  rt_kprintf(&quot;ID:0x%04X RTR len:%d \n&quot;, rxmsg.id, rxmsg.len);
                }
                if(rxmsg.id == 0x123)
                {
                  //can1_send_0x123();
                  if(rxmsg.data == 0)
                  {
                        flag_key = 0;//0表达左
                  }
                  else if (rxmsg.data == 1) {
                        flag_key = 1;//1表示右
                  }

                }
            }else//数据帧
            {
                if(rxmsg.ide == RT_CAN_EXTID)//扩展帧
                {
                  rt_kprintf(&quot;ID:0x%08X len:%d &quot;, rxmsg.id, rxmsg.len);
                  for (int i = 0; i &lt; rxmsg.len; i++)
                  {
                            rt_kprintf(&quot; %02X&quot;, rxmsg.data<i>);
                  }
                  rt_kprintf(&quot;\n&quot;);
                }else
                {
                  rt_kprintf(&quot;ID:0x%04X len:%d &quot;, rxmsg.id, rxmsg.len);
                  for (int i = 0; i &lt; rxmsg.len; i++)
                  {
                            rt_kprintf(&quot; %02X&quot;, rxmsg.data<i>);
                  }
                  rt_kprintf(&quot;\n&quot;);
                  //can1_send_0x123();
                     if(rxmsg.data == 0)
                     {
                         flag_key = 0;//0表达左
                     }
                     else if (rxmsg.data == 1) {
                         flag_key = 1;//0表达左
                     }
                }
            }

void disp_flag(void)
{
    if (flag_key == 0) {
      ssd1306_Fill(Black);
      ssd1306_SetCursor(2,16);
      ssd1306_WriteString(&quot;LEFT&quot;, Font_16x26, White);
      ssd1306_UpdateScreen();
      flag_key == 3;
    }
    else if (flag_key == 1) {
      ssd1306_Fill(Black);
      ssd1306_SetCursor(48,16);
      ssd1306_WriteString(&quot;RIGHT&quot;, Font_16x26, White);
      ssd1306_UpdateScreen();
      flag_key == 3;
    }
}</i></i></code></pre>

<p><i><i>最后上视频,由于stm32的开发板没有N32G45的好用,按得有点吃力,大家见笑!</i></i></p>

<p><br />
<iframe allowfullscreen="true" frameborder="0" height="510" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&amp;lessonid=32430" style="background:#eee;margin-bottom:10px;" width="700"></iframe><br />
<br />
<br />
<i><i>&nbsp;</i></i></p>
页: [1]
查看完整版本: 【国民技术N32G457评测】十一 N32G45 与STM32 CAN通信实例