[活动专区] AT-START-F425测评】-杂谈

[复制链接]
 楼主| 一路向北lm 发表于 2022-3-1 22:58 | 显示全部楼层 |阅读模式
AD, ar
2022  2- 28收到板子了,板子很美,很简约
50753621e3485e188b.png

9235621e348e33f07.png
 楼主| 一路向北lm 发表于 2022-3-1 22:59 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-1 23:15 编辑

杂谈1  先来说说资料
资料很详细,大家都可以来这里下载  https://www.arterytek.com/cn/product/AT32F425.jsp#Resource
72804621e357bb3733.png
什么pack、lib、bsp ….这里都有,下载下来就ok啦!我来吐槽一下哈,为啥这么重要的参考手册没有目录,没有目录,没有目录!下面这个是我自己添加的,弄好传上来给大家,没有目录是真的不方便啊,友情提示一下官方!
57508621e369a3a4fc.png



 楼主| 一路向北lm 发表于 2022-3-1 22:59 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-5 23:48 编辑

杂谈2  五行代码点灯(寄存器)!


下载过官方的demo bsp的同学都已经把跑马灯给点亮了吧!我这里就简单一些啦,自己从Bsp里移植过来一个简单的工程,把灯给点一下吧,我这里虽然也是点灯,但不是用库来点哦!来个逼格点的,寄存器点灯,啥也不干,5行代码点灯!我觉得更加有意思哈!
大致看了一哈原理图 LED2接到了 PC2 ,我这里只需要简单配置一哈PC2即可,无需考虑什么系统时钟哈,反正它能亮哈!
  1. CRM->ahben_bit.gpiocen = 1;    //使能GPIOC
  2.   GPIOC->cfgr_bit.iomc2 = 0x01;  //普通IO
  3.   GPIOC->omode_bit.om2 = 0;      //推挽
  4.   GPIOC->pull_bit.pull2 = 0x00;  //PULL_NONE
  5.   GPIOC->odt_bit.odt2 = 0;       //输出低

5506621e39925071a.png
 楼主| 一路向北lm 发表于 2022-3-1 22:59 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-2 22:39 编辑

杂谈3  发送21ic网址到串口助手

寄存器点灯后,再来个寄存器操作串口,同样几行代码,串口就可以发送数据到串口助手啦!
57395621f8151419ca.png
  1. uint8_t tab_t[12] = "www.21ic.com";

  2. int main(void)
  3. {
  4.      system_clock_config();   
  5.      CRM->ahben_bit.gpioaen = 1;    //使能GPIOA
  6.      CRM->apb2en_bit.usart1en = 1;  //使能USART
  7.      GPIOA->cfgr_bit.iomc9 = 0x02;  //PA9 复用功能
  8.      GPIOA->odrvr_bit.odrv9 = 1;
  9.      GPIOA->muxh_bit.muxh9 = 1;
  10.      GPIOA->omode_bit.om9 = 0;      //推挽
  11.      GPIOA->pull_bit.pull9 = 0;  //PULL_NONE
  12.      USART1->baudr_bit.div = 0x341;  //115200
  13.      USART1->ctrl1_bit.ten = 1;      //TX EN
  14.      USART1->ctrl1_bit.uen = 1;      //USART EN  
  15.      for(uint8_t i=0;i<12;i++)
  16.      {
  17.         USART1->dt_bit.dt = tab_t[i];
  18.         while(USART1->sts_bit.tdc == RESET);
  19.      }
  20.   while(1)
  21.   {
  22.   }
  23. }
67951621f81a5957ff.png

 楼主| 一路向北lm 发表于 2022-3-1 22:59 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-6 00:12 编辑

杂谈4  定时器中断功能验证

这次简单验证一下定时器的中断功能,同样使用寄存器写了一个定时器定时器中断LED2翻转的例子,大家忽略我拿Time1 大马拉小车的操作哈!
  1. uint8_t timeFlag;
  2. int main(void)
  3. {  
  4.   system_clock_config();  
  5.   //初始化LED2
  6.   CRM->ahben_bit.gpiocen = 1;    //使能GPIOC
  7.   GPIOC->cfgr_bit.iomc2 = 0x01;  //普通IO
  8.   GPIOC->omode_bit.om2 = 0;      //推挽
  9.   GPIOC->pull_bit.pull2 = 0x00;  //PULL_NONE
  10.   GPIOC->odt_bit.odt2 = 1;       //输出高  
  11.    
  12.   // TMR1 1S中断一次  (96M/div) * pr
  13.   CRM->apb2en_bit.tmr1en = 1;    //使能TMR1
  14.   TMR1->pr = 9999;   //  周期为10000
  15.   TMR1->div = (9600-1);   //分频系数 9600
  16.   TMR1->swevt_bit.ovfswtr = 1;  //软件触发溢出事件
  17.   TMR1->iden |= (1<<0);         //OVFIEN 开启中断使能
  18.   TMR1->ctrl1_bit.cnt_dir = 0;  //向上计数
  19.   TMR1->ctrl1_bit.tmren = 1;    //使能定时器1

  20. // 配置中断分组
  21.   nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  22.   nvic_irq_enable(TMR1_BRK_OVF_TRG_HALL_IRQn, 0, 0);

  23.   while(1)
  24.   {
  25.       if(timeFlag)
  26.          GPIOC->odt_bit.odt2 = 1;    //输出高
  27.       else
  28.          GPIOC->odt_bit.odt2 = 0;     //输出高
  29.    
  30.   }
  31. }

  32. // TMR1 中断函数
  33. void TMR1_BRK_OVF_TRG_HALL_IRQHandler(void)
  34. {
  35.   if(tmr_flag_get(TMR1, TMR_OVF_FLAG) != RESET)
  36.   {
  37.     /* add user code... */

  38.           if(timeFlag)
  39.              timeFlag = 0;
  40.           else
  41.              timeFlag = 1;
  42.       
  43.     tmr_flag_clear(TMR1, TMR_OVF_FLAG);
  44.   }
  45. }



 楼主| 一路向北lm 发表于 2022-3-1 22:59 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-8 21:44 编辑

杂谈5   定时器来输出一个PWM吧!

上次我们验证了定时器中断功能,这次我们来验证定时器的PWM输出功能,同样写了一个定时器定时器输出PWM的例子,这次我用Timer3吧,省得大家又说我瞎操作哈!
  1. int main(void)
  2. {
  3.   system_clock_config();

  4.   /* peripheral clocks configuration */
  5.   crm_configuration();

  6.   /* gpio configuration */
  7.   gpio_configuration();

  8.   /* compute the prescaler value */
  9.   prescaler_value = (uint16_t)(system_core_clock / 96000000) - 1;

  10.   /* tmr3 time base configuration */
  11.   tmr_base_init(TMR3, 500, prescaler_value);
  12.   tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
  13.   tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);

  14.   tmr_output_default_para_init(&tmr_oc_init_structure);
  15.   tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  16.   tmr_oc_init_structure.oc_idle_state = FALSE;
  17.   tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  18.   tmr_oc_init_structure.oc_output_state = TRUE;
  19.   tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
  20.   tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, c1dt_val);
  21.   tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_1, TRUE);

  22.   tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
  23.   tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_2, c2dt_val);
  24.   tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_2, TRUE);

  25.   tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_3, &tmr_oc_init_structure);
  26.   tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_3, c3dt_val);
  27.   tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_3, TRUE);

  28.   tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
  29.   tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, c4dt_val);
  30.   tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_4, TRUE);

  31.   tmr_period_buffer_enable(TMR3, TRUE);

  32.   /* tmr enable counter */
  33.   tmr_counter_enable(TMR3, TRUE);
  34.   while(1)
  35.   {
  36.   }
  37. }
在PA6端子上输出了 192k 的PWM波形
8013862275d9c71197.png
9668662275daa7a7fe.png




 楼主| 一路向北lm 发表于 2022-3-1 22:59 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-16 11:08 编辑

杂谈6  串口空闲中断 + DMA 不定长数据帧接收
串口不定长数据帧扮演者很重要的角色,我想一个写通讯的程序不会撸这段代码怎么能行呢?借着雅特力这块宝地,开始造起来!
第一步串口GPIO初始化
  1. //****************************************************************
  2. //******  串口GPIO初始化函数
  3. //******  输入参数: 无
  4. //******  返回值:   无
  5. //****************************************************************
  6. static void PhyUartGpioInit()
  7. {
  8.   gpio_init_type gpio_init_struct;
  9.   crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  10.   gpio_default_para_init(&gpio_init_struct);
  11.    
  12.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  13.   gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  14.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  15.   gpio_init_struct.gpio_pins = GPIO_PINS_9|GPIO_PINS_10;
  16.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  17.   gpio_init(GPIOA, &gpio_init_struct);
  18.    
  19.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE9, GPIO_MUX_1);
  20.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE10, GPIO_MUX_1);
  21.    
  22. }
第二步 串口参数初始化
  1. //****************************************************************
  2. //******  串口参数初始化函数
  3. //******  输入参数: uint32_t baudrate 波特率
  4. //******  返回值:   无
  5. //****************************************************************
  6. static void  PhyUartCoreInit(uint32_t baudrate)
  7. {
  8.    crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
  9.    usart_init(USART1, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
  10.    usart_parity_selection_config(USART1, USART_PARITY_NONE);
  11.    usart_transmitter_enable(USART1, TRUE);
  12.    usart_receiver_enable(USART1, TRUE);
  13.    usart_dma_receiver_enable(USART1, TRUE);
  14.    nvic_irq_enable(USART1_IRQn, 0, 0);
  15.    usart_interrupt_enable(USART1, USART_IDLE_INT, TRUE);   
  16.    usart_enable(USART1, TRUE);        
  17. }
第三步 串口DMA初始化
  1. //****************************************************************
  2. //******  串口DMA参数初始化函数
  3. //******  输入参数: 无
  4. //******  返回值:   无
  5. //****************************************************************
  6. void PhyUartDmaInit()
  7. {
  8.   dma_init_type dma_init_struct;  
  9.   crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);  
  10.   dma_reset(DMA1_CHANNEL3);
  11.   dma_default_para_init(&dma_init_struct);  
  12.   dma_init_struct.buffer_size = USART_RX_BUFFER_SIZE;
  13.   dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
  14.   dma_init_struct.memory_base_addr = (uint32_t)UartRxBuffer;
  15.   dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
  16.   dma_init_struct.memory_inc_enable = TRUE;
  17.   dma_init_struct.peripheral_base_addr = (uint32_t)&USART1->dt;
  18.   dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
  19.   dma_init_struct.peripheral_inc_enable = FALSE;
  20.   dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
  21.   dma_init_struct.loop_mode_enable = FALSE;
  22.   dma_init(DMA1_CHANNEL3, &dma_init_struct);
  23.   dma_channel_enable(DMA1_CHANNEL3, TRUE);
  24. }
第四步 串口初始化,以上三个**合力!
  1. //****************************************************************
  2. //******  串口初始化函数
  3. //******  输入参数: 无
  4. //******  返回值:   无
  5. //****************************************************************
  6. void PhyUartInit()
  7. {
  8.     PhyUartGpioInit();
  9.     PhyUartDmaInit();
  10.     PhyUartCoreInit(115200);
  11. }
第五步 最关键的一步,串口空闲中断处理函数!
  1. //****************************************************************
  2. //******  串口中断处理函数
  3. //******  输入参数: 无
  4. //******  返回值:   无
  5. //****************************************************************
  6. void USART1_IRQHandler()
  7. {
  8.   uint16_t rc_len;
  9.   if(usart_flag_get(USART1, USART_IDLEF_FLAG) != RESET)
  10.   {
  11.       usart_data_receive(USART1);
  12.       dma_channel_enable(DMA1_CHANNEL3,FALSE);
  13.       rc_len = USART_RX_BUFFER_SIZE - dma_data_number_get(DMA1_CHANNEL3);
  14.       dma_data_number_set(DMA1_CHANNEL3, USART_RX_BUFFER_SIZE);
  15.       dma_channel_enable(DMA1_CHANNEL3,TRUE);
  16.       if((UartRxBuffer[1]>=0x80) && (UartRxBuffer[1]<=0x90))  //使用命令码过滤错误帧
  17.       {
  18.             UartRecvSta = 1;
  19.             UartFramRecvLen = rc_len;         
  20.       }
  21.       else
  22.       {
  23.             UartFramRecvLen = 0;
  24.             UartRecvSta = 0;
  25.       }      
  26.   }
  27. }

最后,在补充一些变量哈,大家知道它是怎么来的。
  1. #define  USART_RX_BUFFER_SIZE     1024
  2. uint8_t UartRxBuffer[1024];   //串口接收帧Buffer
  3. uint16_t UartFramRecvLen;     //串口接收帧长度
  4. uint8_t  UartRecvSta;         //串口接收帧完成标志位


 楼主| 一路向北lm 发表于 2022-3-1 22:59 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-16 11:22 编辑

杂谈7     内置Flash操作  擦除 读 写
内置Flash的擦除,使用页擦除,当然也可以全片擦除
  1. //****************************************************************
  2. //******  Flash 擦除函数
  3. //******  输入参数: uint32_t addr:擦除的首地址  uint32_t len:擦除的长度
  4. //******  返回值:   err 错误码
  5. //****************************************************************
  6. uint8_t FlashErase(uint32_t addr,uint32_t len)
  7. {
  8.     uint16_t sector = 0;
  9.     uint8_t sta = FLASH_OPERATE_DONE;
  10.       //1.根据擦除长度 判断需要擦除的页数
  11.        if(len%1024) sector = len/1024 + 1;
  12.        else sector = len/1024;
  13.       //2.遍历页数擦除数据
  14.        flash_unlock();
  15.        for(uint16_t i=0;i<sector;i++)
  16.        {
  17.          sta = flash_sector_erase(addr + i*1024);
  18.            if(sta != FLASH_OPERATE_DONE)
  19.            {
  20.              err = ERROR_ERASE;
  21.              flash_lock();
  22.              break;         
  23.            }               
  24.        }
  25.        flash_lock();
  26.   return  err;  
  27. }
2.内置Flash 编程函数,使用页所在的地址尽心编程
  1. //****************************************************************
  2. //******  Flash 编程函数   
  3. //******  输入参数: 无
  4. //******  返回值:   err 错误码
  5. //****************************************************************
  6. uint8_t FlashProgram(uint32_t addr)
  7. {
  8.    uint8_t sta = FLASH_OPERATE_DONE;
  9.        //每次编程256个字节数据,即一页的数据
  10.        flash_unlock();
  11.        for(uint16_t i=0;i<256;i++)
  12.        {
  13.            sta = flash_byte_program(addr+i, UartRxBuffer[6+i]);
  14.            if(sta != FLASH_OPERATE_DONE)
  15.            {
  16.               err = ERROR_PROGRAM;
  17.               flash_lock();
  18.               break;         
  19.            }
  20.        }
  21.        flash_lock();
  22.   return  err;  
  23. }
3. 读取Flash
  1. /读取Flash参数
  2.   uint8_t i;
  3.   uint8_t  p_buffer[8];
  4.   uint32_t read_addr = 0x08003000;
  5.   for(i = 0; i < 8; i++)
  6.   {
  7.      p_buffer[i] = *(uint8_t*)(read_addr);
  8.      read_addr ++;
  9.   }


 楼主| 一路向北lm 发表于 2022-3-1 22:59 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-16 11:11 编辑

杂谈8  SPI-Flash 操作  
 楼主| 一路向北lm 发表于 2022-3-1 23:08 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-16 11:11 编辑

杂谈9  不能不玩的 USB外设
 楼主| 一路向北lm 发表于 2022-3-1 23:08 | 显示全部楼层
本帖最后由 一路向北lm 于 2022-3-16 12:26 编辑

杂谈10   使用雅特力 MCU 制作的脱机烧录器 (暂不开源)
PCB设计如下:
2155762315a26113c6.png
7282762315a38dc65d.png

MDK工程
脱机烧录器(MDK).png

1.BootLoader工程
6005762315a75eb87b.png
2. APP工程
7336162315aaca15fe.png

Qt 上位机软件
1.更新APP固件 上位机
1400462315b3584c50.png
5809662315b77132de.png

2.脱机烧录器上位机(完善中)





chenjun89 发表于 2022-3-2 07:46 来自手机 | 显示全部楼层
白色很不错啊
littlelida 发表于 2022-3-4 14:51 | 显示全部楼层
杂谈这种形式很不错,言简意赅
看来楼主后面还打算持续更新啊,期待
 楼主| 一路向北lm 发表于 2022-3-4 15:56 | 显示全部楼层
littlelida 发表于 2022-3-4 14:51
杂谈这种形式很不错,言简意赅
看来楼主后面还打算持续更新啊,期待

是的,必须更新,精彩在后面
muyichuan2012 发表于 2022-3-4 16:45 | 显示全部楼层
“为啥这么重要的参考手册没有目录,没有目录”
--感谢反馈,下一版RM会加上书签目录。
 楼主| 一路向北lm 发表于 2022-3-5 23:07 | 显示全部楼层
muyichuan2012 发表于 2022-3-4 16:45
“为啥这么重要的参考手册没有目录,没有目录”
--感谢反馈,下一版RM会加上书签目录。
...

谢谢哈
cr315 发表于 2022-3-8 10:30 | 显示全部楼层
期待楼主继续杂谈起来哟
 楼主| 一路向北lm 发表于 2022-3-16 11:04 | 显示全部楼层
开心
 楼主| 一路向北lm 发表于 2022-3-16 11:04 | 显示全部楼层
在家办公第三天啦,啥时候是个头
mxkw0514 发表于 2022-3-17 09:32 | 显示全部楼层
一路向北lm 发表于 2022-3-1 23:08
杂谈10   使用雅特力 MCU 制作的脱机烧录器 (暂不开源)
PCB设计如下:

脱机烧录有什么好处呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3837

帖子

81

粉丝
快速回复 在线客服 返回列表 返回顶部

293

主题

3837

帖子

81

粉丝
快速回复 在线客服 返回列表 返回顶部