打印
[活动专区]

AT-START-F425测评】-杂谈

[复制链接]
1606|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AD, ar
2022  2- 28收到板子了,板子很美,很简约



使用特权

评论回复
沙发
一路向北lm|  楼主 | 2022-3-1 22:59 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-1 23:15 编辑

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



使用特权

评论回复
板凳
一路向北lm|  楼主 | 2022-3-1 22:59 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-5 23:48 编辑

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


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

使用特权

评论回复
地板
一路向北lm|  楼主 | 2022-3-1 22:59 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-2 22:39 编辑

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

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

int main(void)
{
     system_clock_config();   
     CRM->ahben_bit.gpioaen = 1;    //使能GPIOA
     CRM->apb2en_bit.usart1en = 1;  //使能USART
     GPIOA->cfgr_bit.iomc9 = 0x02;  //PA9 复用功能
     GPIOA->odrvr_bit.odrv9 = 1;
     GPIOA->muxh_bit.muxh9 = 1;
     GPIOA->omode_bit.om9 = 0;      //推挽
     GPIOA->pull_bit.pull9 = 0;  //PULL_NONE
     USART1->baudr_bit.div = 0x341;  //115200
     USART1->ctrl1_bit.ten = 1;      //TX EN
     USART1->ctrl1_bit.uen = 1;      //USART EN  
     for(uint8_t i=0;i<12;i++)
     {
        USART1->dt_bit.dt = tab_t[i];
        while(USART1->sts_bit.tdc == RESET);
     }
  while(1)
  {
  }
}

使用特权

评论回复
5
一路向北lm|  楼主 | 2022-3-1 22:59 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-6 00:12 编辑

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

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

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

  while(1)
  {
      if(timeFlag)
         GPIOC->odt_bit.odt2 = 1;    //输出高
      else
         GPIOC->odt_bit.odt2 = 0;     //输出高
   
  }
}

// TMR1 中断函数
void TMR1_BRK_OVF_TRG_HALL_IRQHandler(void)
{
  if(tmr_flag_get(TMR1, TMR_OVF_FLAG) != RESET)
  {
    /* add user code... */

          if(timeFlag)
             timeFlag = 0;
          else
             timeFlag = 1;
      
    tmr_flag_clear(TMR1, TMR_OVF_FLAG);
  }
}



使用特权

评论回复
6
一路向北lm|  楼主 | 2022-3-1 22:59 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-8 21:44 编辑

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

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

  /* peripheral clocks configuration */
  crm_configuration();

  /* gpio configuration */
  gpio_configuration();

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

  /* tmr3 time base configuration */
  tmr_base_init(TMR3, 500, prescaler_value);
  tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
  tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);

  tmr_output_default_para_init(&tmr_oc_init_structure);
  tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_oc_init_structure.oc_idle_state = FALSE;
  tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_oc_init_structure.oc_output_state = TRUE;
  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, c1dt_val);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_1, TRUE);

  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_2, c2dt_val);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_2, TRUE);

  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_3, &tmr_oc_init_structure);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_3, c3dt_val);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_3, TRUE);

  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, c4dt_val);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_4, TRUE);

  tmr_period_buffer_enable(TMR3, TRUE);

  /* tmr enable counter */
  tmr_counter_enable(TMR3, TRUE);
  while(1)
  {
  }
}
在PA6端子上输出了 192k 的PWM波形






使用特权

评论回复
7
一路向北lm|  楼主 | 2022-3-1 22:59 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-16 11:08 编辑

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

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


使用特权

评论回复
8
一路向北lm|  楼主 | 2022-3-1 22:59 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-16 11:22 编辑

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


使用特权

评论回复
9
一路向北lm|  楼主 | 2022-3-1 22:59 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-16 11:11 编辑

杂谈8  SPI-Flash 操作  

使用特权

评论回复
10
一路向北lm|  楼主 | 2022-3-1 23:08 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-16 11:11 编辑

杂谈9  不能不玩的 USB外设

使用特权

评论回复
11
一路向北lm|  楼主 | 2022-3-1 23:08 | 只看该作者
本帖最后由 一路向北lm 于 2022-3-16 12:26 编辑

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



MDK工程


1.BootLoader工程

2. APP工程


Qt 上位机软件
1.更新APP固件 上位机



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





使用特权

评论回复
12
chenjun89| | 2022-3-2 07:46 | 只看该作者
白色很不错啊

使用特权

评论回复
13
littlelida| | 2022-3-4 14:51 | 只看该作者
杂谈这种形式很不错,言简意赅
看来楼主后面还打算持续更新啊,期待

使用特权

评论回复
14
一路向北lm|  楼主 | 2022-3-4 15:56 | 只看该作者
littlelida 发表于 2022-3-4 14:51
杂谈这种形式很不错,言简意赅
看来楼主后面还打算持续更新啊,期待

是的,必须更新,精彩在后面

使用特权

评论回复
15
muyichuan2012| | 2022-3-4 16:45 | 只看该作者
“为啥这么重要的参考手册没有目录,没有目录”
--感谢反馈,下一版RM会加上书签目录。

使用特权

评论回复
16
一路向北lm|  楼主 | 2022-3-5 23:07 | 只看该作者
muyichuan2012 发表于 2022-3-4 16:45
“为啥这么重要的参考手册没有目录,没有目录”
--感谢反馈,下一版RM会加上书签目录。
...

谢谢哈

使用特权

评论回复
17
cr315| | 2022-3-8 10:30 | 只看该作者
期待楼主继续杂谈起来哟

使用特权

评论回复
18
一路向北lm|  楼主 | 2022-3-16 11:04 | 只看该作者
开心

使用特权

评论回复
19
一路向北lm|  楼主 | 2022-3-16 11:04 | 只看该作者
在家办公第三天啦,啥时候是个头

使用特权

评论回复
20
mxkw0514| | 2022-3-17 09:32 | 只看该作者
一路向北lm 发表于 2022-3-1 23:08
杂谈10   使用雅特力 MCU 制作的脱机烧录器 (暂不开源)
PCB设计如下:

脱机烧录有什么好处呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

275

主题

3784

帖子

76

粉丝