您尚未登录。

#1 全志 SOC » 请教一下有关F1C100S裸跑串口接收问题 » 2023-12-27 11:13:52

O5_13
回复: 0

本人现在需要开发一个项目,串口接收波特率需要为921600,但是现在经过测试在接收超过100bytes长数据时会出现接收错误和不完全的情况,初始化代码如下,求大佬们帮帮忙解答一下

void sys_clock_init(void)
{
  uint32_t val;

  // 设置PLL和CPU-PLL的锁定延迟时间
  write32(F1C100S_CCU_BASE + CCU_PLL_STABLE_TIME0, 0x1ff);
  write32(F1C100S_CCU_BASE + CCU_PLL_STABLE_TIME1, 0x1ff);

  // 先把CPU时钟源设置为24Mhz晶振
  val = read32(F1C100S_CCU_BASE + CCU_CPU_CFG);
  val &= ~(0x3 << 16);
  val |= (0x1 << 16);
  write32(F1C100S_CCU_BASE + CCU_CPU_CFG, val);
  sdelay(100);

  // 设置PLL_VIDEO(N=66,M=8)
  write32(F1C100S_CCU_BASE + CCU_PLL_VIDEO_CTRL, 0x81004107);
  sdelay(100);
  // 设置PLL_PERIPH(N=25,M=1) to 600Mhz
 // write32(F1C100S_CCU_BASE + CCU_PLL_PERIPH_CTRL, 0x80041800);
    // 设置PLL_PERIPH(N=26,M=1) to 624Mhz
  write32(F1C100S_CCU_BASE + CCU_PLL_PERIPH_CTRL, 0x80041900);
  sdelay(100);
  // 设置AHB/APB/HCLKC的工作频率
#define HCLKC_DIV (0)         // HCLKC=CPUCLK/1
#define AHB_CLK_SRC_SEL (3)   // AHB source is (PLL_PERIPH/AHB_PRE_DIV)
#define APB_CLK_RATIO (1)     // APB_CLK=AHB_CLK/2=100Mhz           208/2=104Mhz
#define AHB_PRE_DIV (2)       // AHB_source=600/3=200Mhz            624/3=208Mhz
#define AHB_CLK_DIV_RATIO (0) // AHB_CLK=AHB_source/1=200Mhz        208Mhz
  write32(F1C100S_CCU_BASE + CCU_AHB_APB_CFG, (
              (HCLKC_DIV << 16) |
              (AHB_CLK_SRC_SEL << 12) |
              (APB_CLK_RATIO << 8) |
              (AHB_PRE_DIV << 6) |
              (AHB_CLK_DIV_RATIO << 4)
          ));
  sdelay(100);
  // 开启DE的front-end和back-end的DCLK门?
  val = read32(F1C100S_CCU_BASE + CCU_DRAM_CLK_GATE);
  val |= (0x1 << 26) | (0x1 << 24);
  write32(F1C100S_CCU_BASE + CCU_DRAM_CLK_GATE, val);
  sdelay(100);
  // 配置PLL_CPU的值
  clock_set_pll_cpu(720000000);
  // 把CPU时钟源设置为PLL_CPU
  val = read32(F1C100S_CCU_BASE + CCU_CPU_CFG);
  val &= ~(0x3 << 16);
  val |= (0x2 << 16);
  write32(F1C100S_CCU_BASE + CCU_CPU_CFG, val);
  sdelay(100);
}



static void uart1_init(UART_MOD_TypeDef* module)
{
    uint32_t addr,val; 
    
  /*初始化接控制板串口PA2、PA3*/
  addr=PIO_REG_BASE+PA_OFFSET+CFG0_OFFSET;
  val  = read32(addr);                              //读PA寄存器值
  val &= ~(0Xf<<((3&0x7)<<2));                      //与0fff,清除PA3
  val &= ~(0Xf<<((2&0x7)<<2));                      //与f0ff,清除PA2
  val |= ((5 & 0x7)<<((3 & 0x7)<<2));               //PA3位或0x5
  val |= ((5 & 0x7)<<((2 & 0x7)<<2));               //PA2位或0x5          目前寄存器,55aa,aa未知
  write32(addr,val);
  /*    打开UART1时钟树  */
  addr=0x01c20000+0x68;
  val=read32(addr);
  val |= 1<<21 ;
  write32(addr,val);
  /*    软件复位UART1   */
  addr=0x01c20000+0x02d0;
  val  = read32(addr);
  val |= 1<<21;
  write32(addr,val);
  
  /* Config uart1 to 921600-8-1-0 */
  addr = 0x01c25400;
  write32(addr + 0x04, 0x0);
  write32(addr + 0x08, 0xf7);
  write32(addr + 0x10, 0x0);
  val = read32(addr + 0x0c);
  val |= (1 << 7);
  write32(addr + 0x0c, val);                        //选择波特率传感器
  write32(addr + 0x00, 0x07 & 0xff);                //低八位
  write32(addr + 0x04, (0x07 >> 8) & 0xff);         //高八位
  val = read32(addr + 0x0c);                        //读传感器
  val &= ~(1 << 7);                                 //清零分频寄存器位
  write32(addr + 0x0c, val);                        //锁位
  
  val = read32(addr + 0x04);                        //锁位后读取中断标志位启动接收中断
  val |= 0x01;
  write32(addr + 0x04,val);                         //写入数据
  
  val = read32(addr + 0x0c);                        //再次读串口寄存器
  val &= ~0x1f;                                     //只保留高三位,后五位清零
  val |= (0x3 << 0) | (0 << 2) | (0x0 << 3);
  write32(addr + 0x0c, val);
  

  // 配置中断
  f1c100s_intc_set_isr(F1C100S_IRQ_UART1, uart1_irq);
  f1c100s_intc_enable_irq(F1C100S_IRQ_UART1);
}

#2 全志 SOC » 请教一下有关F1C100S串口接收问题 » 2023-12-13 17:29:50

O5_13
回复: 1

各位大佬,我现在开发一个裸跑基于RTX+emwin的项目,其中使用了UART2作为DEBUG接口,UART1作为通讯端口。UART1每次接收接收数据长度会大于150字节,查手册看到fifo只有64字节,不知道能否使用FIFO方式接收。现在想使用串口接收中断方式接收数据,但是不知道如何正确操作,调用了是能中断函数后程序会卡死,注释掉又能正常工作,请教一下大佬们该如何操作。

void sys_uart_init(void)
{
  uint32_t addr;
  uint32_t val;

    
  /* Config GPIOE1 and GPIOE0 to txd2 and rxd2 */
  addr = PIO_REG_BASE+PE_OFFSET+CFG0_OFFSET;         //PE7所在寄存器
  val = read32(addr);
  val &= ~(0xf << ((7 & 0x7) << 2));                //0FFF_FFFF,PE7清零,其他位不变
  val |= ((0x3 & 0x7) << ((7 & 0x7) << 2));         //PE7位写入101,复用为TX
  write32(addr, val);

  addr = PIO_REG_BASE+PE_OFFSET+CFG1_OFFSET;         //PE8所在寄存器
  val = read32(addr);
  val &= ~(0xf << ((0 & 0x7) << 2));                //FFF0,PE8清零,其他位不变
  val |= ((0x3 & 0x7) << ((0 & 0x7) << 2));
  write32(addr, val);

  /* Open the clock gate for uart2 */
  addr = 0x01c20068;
  val = read32(addr);
  val |= 1 << 22;
  write32(addr, val);

  /* Deassert uart2 reset */
  addr = 0x01c202d0;                                //总线软复位寄存器,Bus Software Reset Register 2
  val = read32(addr);
  val |= 1 << 22;
  write32(addr, val);

  /* Config uart2 to 921600-8-1-0 */
  addr = 0x01c25800;
  write32(addr + 0x04, 0x0);
  write32(addr + 0x08, 0xf7);
  write32(addr + 0x10, 0x0);
  val = read32(addr + 0x0c);
  val |= (1 << 7);
  write32(addr + 0x0c, val);                        //选择波特率传感器
  write32(addr + 0x00, 0x07 & 0xff);                //低八位
  write32(addr + 0x04, (0x07 >> 8) & 0xff);         //高八位
  val = read32(addr + 0x0c);                        //读传感器
  val &= ~(1 << 7);                                 //清零分频寄存器位
  write32(addr + 0x0c, val);                        //锁位
  val = read32(addr + 0x0c);                        //再次读串口寄存器
  val &= ~0x1f;                                     //只保留高三位,后五位清零
  val |= (0x3 << 0) | (0 << 2) | (0x0 << 3);
  write32(addr + 0x0c, val);
  
  /*初始化接控制板串口PA2、PA3*/
  addr=PIO_REG_BASE+PA_OFFSET+CFG0_OFFSET;
  val  = read32(addr);                              //读PA寄存器值
  val &= ~(0Xf<<((3&0x7)<<2));                      //与0fff,清除PA3
  val &= ~(0Xf<<((2&0x7)<<2));                      //与f0ff,清除PA2
  val |= ((5 & 0x7)<<((3 & 0x7)<<2));               //PA3位或0x5
  val |= ((5 & 0x7)<<((2 & 0x7)<<2));               //PA2位或0x5          目前寄存器,55aa,aa未知
  write32(addr,val);
  /*    打开UART1时钟树  */
  addr=0x01c20000+0x68;
  val=read32(addr);
  val |= 1<<21 ;
  write32(addr,val);
  /*    软件复位UART2   */
  addr=0x01c20000+0x02d0;
  val  = read32(addr);
  val |= 1<<21;
  write32(addr,val);
  
  /* Config uart1 to 921600-8-1-0 */
  addr = 0x01c25400;
  write32(addr + 0x04, 0x0);
  write32(addr + 0x08, 0xf7);
  write32(addr + 0x10, 0x0);
  val = read32(addr + 0x0c);
  val |= (1 << 7);
  write32(addr + 0x0c, val);                        //选择波特率传感器
  write32(addr + 0x00, 0x07 & 0xff);                //低八位
  write32(addr + 0x04, (0x07 >> 8) & 0xff);         //高八位
  val = read32(addr + 0x0c);                        //读传感器
  val &= ~(1 << 7);                                 //清零分频寄存器位
  write32(addr + 0x0c, val);                        //锁位
  
  val = read32(addr + 0x04);                        //锁位后读取中断标志位启动接收中断
  val |= 0x01;
  write32(addr + 0x04,val);                         //写入数据
  
  val = read32(addr + 0x0c);                        //再次读串口寄存器
  val &= ~0x1f;                                     //只保留高三位,后五位清零
  val |= (0x3 << 0) | (0 << 2) | (0x0 << 3);
  write32(addr + 0x0c, val);
  
//  f1c100s_intc_set_isr(F1C100S_IRQ_UART1,UART1_Rx_irq);       //解除注释程序无法运行
//  f1c100s_intc_enable_irq(F1C100S_IRQ_UART1);                      //解除注释程序无法运行
  
}

static void UART1_Rx_irq(void)
{
    uint8_t data;
    uint32_t addr;
    
    if((read32(0x01c25400+0x14)&&0x01))
    {
        addr=0x01c25400+0x00;
        data=(uint8_t)read32(addr);
        sysprintf("%c\n",data);
    }
}

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn