打印
[活动专区]

【AT-START-F425测评】+迟来的测试+原子风格代码DEMO

[复制链接]
760|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
之前整个小区被隔离半个月,板子放在公司了。刚想回去拿,门卫已经不让出去了。这该死的新冠,真是祸害。
上周三我终于出来了,趁着清明小假,在家调调~对于延迟这么久,对AT版主及21IC管理人员深表歉意~
AT-START-F425是个入门的简易小板,CMSISIDAP+最小系统,当然主打的USB功能还是突出了,外加ARDUINO接口,
挂一些外扩模式也是还能玩一玩的~
在网上下载规格书、原理图及BSP。然后开始按照自己的习惯,创建一个DEMOCode~之前用惯了正点原子大哥的代码风格~
我们就按照这个风格,创建一个工程,分离出重要的几个常见函数,并更改例子的框架~

用惯了ST的,国内的MCU代码风格大同小异,还是比较好上手的。
经查看原理图,于CMSISDAP调试器相连的串口是USART1 (PA9 PA10)。
我们对作为调试用的USART1 (PA9 PA10)进行重点修改,让它成为一个通用的串口配置代码:
我们先看引脚复用的位置:

usart.h
#include "sys.h"
#include "stdio.h"



/**************** define print uart ******************/
#define PRINT_UART                       USART1
#define PRINT_UART_CRM_CLK               CRM_USART1_PERIPH_CLOCK
#define PRINT_UART_TX_PIN                GPIO_PINS_9
#define PRINT_UART_TX_GPIO               GPIOA
#define PRINT_UART_TX_GPIO_CRM_CLK       CRM_GPIOA_PERIPH_CLOCK
#define PRINT_UART_TX_PIN_SOURCE         GPIO_PINS_SOURCE9
#define PRINT_UART_TX_PIN_MUX_NUM        GPIO_MUX_1

#define PRINT_UART_RX_PIN                GPIO_PINS_10
#define PRINT_UART_RX_GPIO               GPIOA
#define PRINT_UART_RX_GPIO_CRM_CLK       CRM_GPIOA_PERIPH_CLOCK
#define PRINT_UART_RX_PIN_SOURCE         GPIO_PINS_SOURCE10
#define PRINT_UART_RX_PIN_MUX_NUM        GPIO_MUX_1

#define PRINT_UART_IRQn                  USART1_IRQn
#define PRINT_UART_IRQHandler                                                 USART1_IRQHandler


#define PRINT_UART_REC_LEN                          200          //定义最大接收字节数 200
#define EN_RRINT_UART_RX                                                 1                //使能(1)/禁止(0)串口1接收
                 
extern u8  PRINT_UART_RX_BUF[PRINT_UART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 PRINT_UART_RX_STA;                         //接收状态标记       


/* printf uart init function */
void uart_print_init(uint32_t baudrate);

#endif
usart.c
#include "usart.h"

u8  PRINT_UART_RX_BUF[PRINT_UART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
//接收状态
//bit15,        接收完成标志
//bit14,        接收到0x0d
//bit13~0,        接收到的有效字节数目
u16 PRINT_UART_RX_STA=0;

/* support printf function, usemicrolib is unnecessary */
#if (__ARMCC_VERSION > 6000000)
  __asm (".global __use_no_semihosting\n\t");
  void _sys_exit(int x)
  {
    x = x;
  }
  /* __use_no_semihosting was requested, but _ttywrch was */
  void _ttywrch(int ch)
  {
    ch = ch;
  }
  FILE __stdout;
#else
#ifdef __CC_ARM
  #pragma import(__use_no_semihosting)
  struct __FILE
  {
    int handle;
  };
  FILE __stdout;
  void _sys_exit(int x)
  {
    x = x;
  }
  /* __use_no_semihosting was requested, but _ttywrch was */
  void _ttywrch(int ch)
  {
    ch = ch;
  }
#endif
#endif

#if defined (__GNUC__) && !defined (__clang__)
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  retargets the c library printf function to the usart.
  * @param  none
  * @retval none
  */
PUTCHAR_PROTOTYPE
{
  while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET);
  usart_data_transmit(PRINT_UART, ch);
  return ch;
}

/**
  * @brief  initialize uart
  * @param  baudrate: uart baudrate
  * @retval none
  */
void uart_print_init(uint32_t baudrate)
{
  gpio_init_type gpio_init_struct;

  /* enable the uart and gpio clock */
  crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
  crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
        crm_periph_clock_enable(PRINT_UART_RX_GPIO_CRM_CLK, TRUE);
       
  gpio_default_para_init(&gpio_init_struct);

  /* configure the uart tx pin */
  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 = PRINT_UART_TX_PIN;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);

  gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM);
       
        /* configure the uart rx pin */
  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 = PRINT_UART_RX_PIN;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(PRINT_UART_RX_GPIO, &gpio_init_struct);

  gpio_pin_mux_config(PRINT_UART_RX_GPIO, PRINT_UART_RX_PIN_SOURCE, PRINT_UART_RX_PIN_MUX_NUM);

  /* configure uart param */
  usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
        usart_parity_selection_config(PRINT_UART, USART_PARITY_NONE);
  usart_transmitter_enable(PRINT_UART, TRUE);
        usart_receiver_enable(PRINT_UART, TRUE);
  usart_enable(PRINT_UART, TRUE);
       
#if EN_RRINT_UART_RX
        /* config usart2 and usart1 nvic interrupt */
  nvic_irq_enable(PRINT_UART_IRQn, 0, 0);
        usart_interrupt_enable(PRINT_UART, USART_RDBF_INT, TRUE);//enable receiver interrupt
//        usart_interrupt_enable(PRINT_UART, USART_TDBE_INT, TRUE);//enable transmitter interrupt
#endif       
}



void PRINT_UART_IRQHandler(void)
{
        u8 Res;
        //
  if(usart_flag_get(USART1, USART_RDBF_FLAG) != RESET)
  {
    /* read one byte from the receive data register */
    Res= usart_data_receive(PRINT_UART);
                if((PRINT_UART_RX_STA&0x8000)==0)//接收未完成
                {
                        if(PRINT_UART_RX_STA&0x4000)//接收到了0x0d
                        {
                                if(Res!=0x0a)PRINT_UART_RX_STA=0;//接收错误,重新开始
                                else PRINT_UART_RX_STA|=0x8000;        //接收完成了
                        }
                        else //还没收到0X0D
                        {       
                                if(Res==0x0d)PRINT_UART_RX_STA|=0x4000;
                                else
                                {
                                        PRINT_UART_RX_BUF[PRINT_UART_RX_STA&0X3FFF]=Res ;
                                        PRINT_UART_RX_STA++;
                                        if(PRINT_UART_RX_STA>(PRINT_UART_REC_LEN-1))PRINT_UART_RX_STA=0;//接收数据错误,重新开始接收          
                                }                 
                        }
                }
  }

//  if(usart_flag_get(USART1, USART_TDBE_FLAG) != RESET)
//  {

//  }
}

配置不同串口,尽仅需修改头文件即可~
main函数里面调用:
  system_clock_config();
        nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
        delay_init();
        uart_print_init(115200);
  LED_Init();

  while(1)
  {
                if(PRINT_UART_RX_STA&0x8000)
                {                                          
                        len=PRINT_UART_RX_STA&0x3fff;//得到此次接收到的数据长度
                        printf("\r\n您发送的消息为:\r\n");
                        for(t=0;t<len;t++)
                        {   
                                while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET);//等待发送结束                               
                                usart_data_transmit(PRINT_UART, PRINT_UART_RX_BUF[t]);//向串口1发送数据
                        }
                        printf("\r\n\r\n");//插入换行
                        PRINT_UART_RX_STA=0;
                }else
                {
                        times++;
                        if(times%5000==0)
                        {
                                printf("\r\nAT-STRAT-F425 串口实验\r\n");
                                printf("qjp1988113@21ic\r\n\r\n\r\n");
                        }
                        if(times%200==0)printf("请输入数据,以回车键结束\r\n");  
                        if(times%30==0){led0_sta=1-led0_sta;LED0(led0_sta);}//闪烁LED,提示系统正在运行.
                        delay_ms(10);   
                }
  }

调试输出:

其中对于BITBAND 功能的外设的映射失败,无反应,查看半天也未看出问题。
我这里主要对GPIO的输入输出配置。
RM里面的描述:

#define PER_BASE                         0x40000000
#define PER_BITBAND_BASE                 0x42000000

#define BITBAND(addr, bitnum) (PER_BITBAND_BASE + ((addr - PER_BASE) * 32) + ((bitnum) * 4))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414   

#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410

//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入
实际定义LED0=PCout(2),并调用LED0=1;LED=0;无反应~
哪位大侠不吝赐教~

使用特权

评论回复
沙发
sparrow054| | 2022-4-13 15:21 | 只看该作者
代码风格很熟悉

使用特权

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

本版积分规则

111

主题

627

帖子

2

粉丝