之前整个小区被隔离半个月,板子放在公司了。刚想回去拿,门卫已经不让出去了。这该死的新冠,真是祸害。
上周三我终于出来了,趁着清明小假,在家调调~对于延迟这么久,对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;无反应~
哪位大侠不吝赐教~
|