STM32G0x0系列 入门试验代码整理
试验目录
- 1.配置寄存器的方式点亮一盏灯
- 2.寄存器实现灯闪烁
- 3.HAL库实现跑马灯
- 4.按键控制LED灯
- 5.代码编写,通过寄存器发送字符
- 6.代码编写,通过寄存器发送字符串
- 7.代码编写,通过寄存器设置接收字符
- 8.代码编写,通过寄存器设置接收字符串(自己理解出现问题)
- 9.串口编写,通过HAL库进行字符串发送
- 10.重写printf
- 11.重写scanf
- 12.通过串口控制灯的亮灭
- 13.驱动LED屏
- 14.显示图片
- 15.显示中文字符
- 16.显示英文字符
- 17.按键中断试验
- 18.串口中断试验
- 19.显示器时钟试验
- 20.串口接收中断
- 21.利用Systick实现每隔一秒打印一次“hello world”
- 22.自己设计一款软件定时器(注意数据类型为uint32_t)
- 23.通过软件定时器设置灯闪烁1s
- 24.利用定时器实现1秒打印1个“HELLO WORLD”
- 26.调节灯的亮度
- 27.使用PWM方波调节占空比实现功能
- 28.通过调节PWM占空比实现呼吸灯效果
- 29.高低电平交替控制蜂鸣器
- 30.使用PWM信号控制
- 31.单通道单次转换:采集光照传感器的值
- 32.多通道单次转换(在ADC_Settings中开启扫描模式)
- 33.DMA_ADC单通道采集试验
- 34.DMA_ADC多通道采集试验
1.配置寄存器的方式点亮一盏灯
RCC->IOPENR |=1<<1; //开启GPIOB的时钟
GPIOB->MODER &=~(0x03<<4); //将MODER2置为00
GPIOB->MODER |=1<<4; //将MODER2置为01;开启输出模式
GPIOB->OTYPER &=~(1<<2); //推挽输出模式
GPIOB->ODR&=~(1<<2); //设置GPIOB2输出低电平
2.寄存器实现灯闪烁
void Delay(){//自定义函数计数
for(int i =0;i<50;i++){
for(int j=0;j<60000;j++){
}
}
}
void SetValue(){ //灭函数
GPIOB->ODR |=1<<2;
}
void ResetValue(){//亮函数
GPIOB->ODR &=~(1<<2);
}
//main函数
RCC->IOPENR |=1<<1; //开启GPIOB的时钟
GPIOB->MODER &=~(0x03<<4);//将MODER2置为00
GPIOB->MODER |=1<<4;//将MODER2置为01;开启输出模式
GPIOB->OTYPER &=~(1<<2);//推挽输出模式
GPIOB->ODR&=~(1<<2);//设置GPIOB2输出低电平
Delay();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
SetValue();
Delay();
ResetValue();
Delay();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
3.HAL库实现跑马灯
//1.将PB0和PB1和PB2配置为输出模式
//2.设置输出电平为高电平,让灯关闭
HAL_GPIO_WritePin(BLUE_GPIO_Port,BLUE_Pin,GPIO_PIN_RESET);//开启蓝灯
HAL_GPIO_WritePin(GREE_GPIO_Port,GREE_Pin,GPIO_PIN_SET);//关闭绿灯
HAL_GPIO_WritePin(YELLO_GPIO_Port,YELLO_Pin,GPIO_PIN_SET);//关闭黄灯
HAL_Delay(500);
HAL_GPIO_WritePin(BLUE_GPIO_Port,BLUE_Pin,GPIO_PIN_SET);//开启蓝灯
HAL_GPIO_WritePin(GREE_GPIO_Port,GREE_Pin,GPIO_PIN_RESET);//关闭绿灯
HAL_GPIO_WritePin(YELLO_GPIO_Port,YELLO_Pin,GPIO_PIN_SET);//关闭黄灯
HAL_Delay(500);
HAL_GPIO_WritePin(BLUE_GPIO_Port,BLUE_Pin,GPIO_PIN_SET);//开启蓝灯
HAL_GPIO_WritePin(GREE_GPIO_Port,GREE_Pin,GPIO_PIN_SET);//关闭绿灯
HAL_GPIO_WritePin(YELLO_GPIO_Port,YELLO_Pin,GPIO_PIN_RESET);//关闭黄灯
HAL_Delay(500);
4.按键控制LED灯
//1.配置PA8为输入状态
//2.将灯的引脚配置为高电平输出
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8))//读取管脚PA8的状态
{
HAL_Delay(100);//消抖
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8))
{
HAL_GPIO_TogglePin(BLUE_GPIO_Port,BLUE_Pin);//反转灯的状态
HAL_GPIO_TogglePin(YELLO_GPIO_Port,YELLO_Pin);//反转灯的状态
HAL_GPIO_TogglePin(GREE_GPIO_Port,GREE_Pin);//反转灯的状态
}
}
5.代码编写,通过寄存器发送字符
//1.开启USART1串口
//2.设置异步通信模式
//3.配置波特率,字长,校验位,停止位
void SendChar(uint8_t ch)
{
while(!(USART1->ISR&(1<<7)));//重点,0的时候不发,1的时候发送
USART1->TDR=ch;
}
while (1)
{
SendChar('A');//主函数调用
HAL_Delay(1000);
}
6.代码编写,通过寄存器发送字符串
//1.开启USART1串口
//2.设置异步通信模式
//3.配置波特率,字长,校验位,停止位
void SendString(uint8_t * buf)//定义指针类型
{
while(*buf)//这里
{
SendChar(*buf);
buf++;
}
SendChar('\n');
}
7.代码编写,通过寄存器设置接收字符
//1.开启USART1串口
//2.设置异步通信模式
//3.配置波特率,字长,校验位,停止位
uint8_t RecvChar()
{
while(!(USART1->ISR&(1<<5)));//寄存器第5位
return USART1->RDR;//字符在前
}
while (1)
{
uint8_t ch=RecvChar();//接收字符
SendChar(ch);
}
8.代码编写,通过寄存器设置接收字符串(自己理解出现问题)
//1.开启USART1串口
//2.设置异步通信模式
//3.配置波特率,字长,校验位,停止位
uint8_t RecvChar()
{
while(!(USART1->ISR&(1<<5)));//寄存器第5位
return USART1->RDR;//字符在前
}
//字符串结束函数
void RecvString(uint8_t *buf)
{
uint8_t ch;
while(1)
{
ch=RecvChar();
if(ch == ' '|| ch =='\n' )
{
*buf='\0'; //
break; //
}else
{
*buf=ch;
buf++;
}
}
9.串口编写,通过HAL库进行字符串发送
//1.开启USART1串口
//2.设置异步通信模式
//3.配置波特率,字长,校验位,停止位
HAL_UART_Receive(&huart1,buf,sizeof(buf),1000);//将字符放到RDR
HAL_UART_Transmit(&huart1,buf,strlen((char*)buf),1000);//将将字符放到TDR
memset(buf,0,sizeof(buf));//这里得清除
10.重写printf
int fputc(int ch,FILE*S)
{
while(!(USART1->ISR&(1<<7)));
USART1->TDR=ch;
return ch;
}
11.重写scanf
int fgetc(FILE*S)
{
uint8_t ch;
while(!(USART1->ISR &(1<<5)));
ch=USART1->RDR;
return ch;
}
12.通过串口控制灯的亮灭
//1.开启USART1串口
//2.设置异步通信模式
//3.配置波特率,字长,校验位,停止位
//4.设置对应灯的引脚,配置为输出模式并设置为高电平
HAL_UART_Receive(&huart1,buf,sizeof(buf),100);//接收串口的数据
if(strncmp((char*)buf,"B_ON",4)==0)//比较字符串的字符
{
HAL_GPIO_TogglePin(BLUE_GPIO_Port,BLUE_Pin);//反转灯的状态
}
memset(buf,0,sizeof(buf));//清空
13.驱动LED屏
//1.根据厂家给定的手册配置引脚接口
//2.将PB6,PB5,PB4,PB3和PA15配置为输出模式
//3.按照驱动代码中的引脚分别为引脚命名
//4.LCD的GPIO输出速度设置为very high
//5.添加.c和.h到文件目录下
//6.包含头文件
Lcd_Init();//初始化显示器
Lcd_Clear(0x07FF);//设置背景色
14.显示图片
//1.根据厂家给定的手册配置引脚接口
//2.将PB6,PB5,PB4,PB3和PA15配置为输出模式
//3.按照驱动代码中的引脚分别为引脚命名
//4.LCD的GPIO输出速度设置为very high
//5.添加.c和.h到文件目录下
//6.包含头文件
Lcd_Init();//初始化显示器
showimage(gImage_test);//显示图片
15.显示中文字符
//1.根据厂家给定的手册配置引脚接口
//2.将PB6,PB5,PB4,PB3和PA15配置为输出模式
//3.按照驱动代码中的引脚分别为引脚命名
//4.LCD的GPIO输出速度设置为very high
//5.添加.c和.h到文件目录下
//6.包含头文件
Lcd_Init();//初始化显示器
showimage(gImage_test);//显示图片
Gui_DrawFont_1616(10,10,WHITE,RED,CharBuf,3);//只能显示中文字符
16.显示英文字符
//1.根据厂家给定的手册配置引脚接口
//2.将PB6,PB5,PB4,PB3和PA15配置为输出模式
//3.按照驱动代码中的引脚分别为引脚命名
//4.LCD的GPIO输出速度设置为very high
//5.添加.c和.h到文件目录下
//6.包含头文件
Lcd_Init();//初始化显示器
showimage(gImage_test);//显示图片
Gui_DrawFont_GBK16(10,20,WHITE,RED,"HELLO WORLD");//只能显示英文字符
17.按键中断试验
单片机正常执行LED灯闪烁程序,当检测到按键按下时通过串口输出“Key Interrupt!”
//1.将对应灯管脚配置为输出模式
//2.将按键对应管脚配置为输出模式
//3.开USART1使能,并配置为异步通信模式
//4.使能管脚中断
//5.设置按键管脚的中断为外部中断且为上升沿触发
//重写按键上升沿中断函数
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_8)
{
printf("Key Interrupt!");
}
}
//反转灯的状态
while(1)
{
HAL_GPIO_TogglePin(BLUE_GPIO_Port,BLUE_Pin);
HAL_Delay(1000);
}
18.串口中断试验
串口输出“hellowolrd”,当发送完成后触发中断,打印“Transmit Completed!”
//1.开启串口,并设置为异步通信模式
//2.配置波特率,字长,校验位,停止位
//3.开启串口中断使能
HAL_UART_Transmit_IT(&huart1,"hello world",sizeof("hello world"));//以中断模式发送hello world
//重写发送中断函数
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart==&huart1)
{
HAL_UART_Transmit(&huart1,"Transmit Completed!",sizeof("Transmit Completed!"),1000);
}
}
19.显示器时钟试验
//1.根据厂家给定的手册配置引脚接口
//2.将PB6,PB5,PB4,PB3和PA15配置为输出模式
//3.按照驱动代码中的引脚分别为引脚命名
//4.LCD的GPIO输出速度设置为very high
//5.因为功能设置中牵扯到了按键重计时
//6.以中断开启按键
//7.设置按键中断使能
//8.添加.c和.h到文件目录下
//9.包含头文件
void Mytime();
uint8_t timebuf[10]="00:00:00";
uint32_t hour=0,min=0,sec=0;
void Mytime()
{
timebuf[2]=':';timebuf[5]=':';
sec++;
printf("sec %c",sec);
if(sec<60)
{
timebuf[7]=sec%10+48;
timebuf[6]=sec/10+48;
}
else{
sec=0;
timebuf[7]=sec%10+48;
timebuf[6]=sec/10+48;
min++;
if(min<60)
{
timebuf[4]=min%10+48;
timebuf[3]=min/10+48;
}
else{
min=0;
timebuf[4]=min%10+48;
timebuf[3]=min/10+48;
hour++;
if(hour<24)
{
timebuf[1]=hour%10+48;
timebuf[0]=hour/10+48;
}
}
}
Gui_DrawFont_GBK16(10,10,WHITE,RED,timebuf);
HAL_Delay(1000);
}
//重写上升中断使能,当按键按下时,触发上升沿中断
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_8)
{
hour=0,min=0,sec=0;//将其重置为0
}
}
20.串口接收中断
//1.开启串口,并设置为异步通信模式
//2.配置波特率,字长,校验位,停止位
//3.开启串口中断使能
HAL_UART_Receive_IT(&huart1,Recbuf,4);//以中断模式接收4个字符
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//重写中断函数
{
if(huart==&huart1)
{
HAL_UART_Transmit(&huart1,"Uart Recive 4 character!",sizeof("Uart Recive 4 character!"),1000);
}
}
21.利用Systick实现每隔一秒打印一次“hello world”
//1.开启USART1串口
//2.设置串口中断使能
extern int flag;
//systick中断服务
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
flag++;
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
//main
while (1)
{
if(flag == 1000)
{
HAL_UART_Transmit(&huart1,"hello world!",sizeof("hello world!"),1000);
flag=0;
}
22.自己设计一款软件定时器(注意数据类型为uint32_t)
//主程序文件
#include "softtime.h"
void SetTime(MyClock *temp,uint32_t delayms)//1.此处是uint32_t
{
temp->start=HAL_GetTick();//获取当前时间
temp->delay=delayms;//存储用户时间
}
uint32_t CompareTime(MyClock *temp)//1.此处是uint32_t
{
//比较用户时间
if(HAL_GetTick()-temp->start>=temp->delay)
{
return 1;
}else
{
return 0;
}
}
//头文件
#ifndef __SOFTTIME__H__
#define __SOFTTIME__H__
#include "stm32g0xx_hal.h"
typedef struct timer
{
uint32_t start;
uint32_t delay;
}MyClock;
//设置定时时间
void SetTime(MyClock *temp,uint32_t delayms);
//比较定时时间
uint32_t CompareTime(MyClock *temp);
#endif
23.通过软件定时器设置灯闪烁1s
MyClock c1;//先实例化定时器
SetTime(&c1,1000);//设置定时间隔
if(CompareTime(&c1))
{
HAL_GPIO_TogglePin(BLUE_GPIO_Port,BLUE_Pin);//让灯反转
SetTime(&c1,1000);
}
24.利用定时器实现1秒打印1个“HELLO WORLD”
- 必须中断使能,定时器使用的就是中断技术
- 鬼知道是TIM14啊
- 时钟树配置出现RCC,使用RCC可以选择晶体陶瓷振荡器
//鬼知道是TIM14啊
//1.开启USART1使能
//2.配置为异步通信模式
//3.开启RCC
//4.设置为HSE选择晶体陶瓷谐振器
//5.调节AHB总线时钟主频为64MHZ
//6.设置TIM14时钟,开启活动
//7.配置计数设置,设置预分频计数(6400),计数模式(up),自动重装值(10000)
//8.使能TIM14中断
//中断的方式启动定时器
HAL_TIM_Base_Start_IT(&htim14);
//定时器溢出中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim14)//判断定时器是不是tim14触发的
{
HAL_UART_Transmit(&huart1,"HELLO WORLD",sizeof("HELLO WORLD"),1000);
}
}
26.调节灯的亮度
//1.将对应灯的引脚配置为输出模式
//2.电平为高电平
HAL_GPIO_TogglePin(BLUE_GPIO_Port,BLUE_Pin);//翻转灯
HAL_Delay(11);//通过延时调节
27.使用PWM方波调节占空比实现功能
//1.开启RCC,设置为HSE选择晶体陶瓷谐振器
//2.调节AHB总线时钟主频为64MHZ
//3.开启对应的灯的时间模块
//4.设置对应灯的通道(选择了3)
//5.计时设置,预分频值为(64-1),计数模式(up),计数周期(1000)
//6.PWM产生的通道3 设置Pulse为500(脉冲,高电平持续时间)
HAL_TIM_Start(&htim3,TIM_CHANNEL_3);//开启TIM定时器
28.通过调节PWM占空比实现呼吸灯效果
//1.开启RCC,设置为HSE选择晶体陶瓷谐振器
//2.调节AHB总线时钟主频为64MHZ
//3.开启对应的灯的时间模块
//4.设置对应灯的通道(选择了3)
//5.计时设置,预分频值为(64-1),计数模式(up),计数周期(1000)
//6.PWM产生的通道3 设置Pulse为500(脉冲,高电平持续时间)
//ccr决定了占空比,ccr从大到小是灯亮,ccr从小到大是灯灭
while(1)
{
for(i=1000;i>0;i--)
{
TIM3->CRR3=i;
HAL_Delay(1);//1ms减1
}
for(i=0;i<1000;i++)
{
TIM3->CRR3=i;
HAL_Delay(1);//1ms加1
}
}
29.高低电平交替控制蜂鸣器
//1.设置PB7为输出电平模式
while(1)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);//基极接口电平反复反转
HAL_Delay(1);
}
30.使用PWM信号控制
//1.设置PB7为TIM17_CH1N
//2.开启RCC
//3.设置为HSE选择晶体陶瓷谐振器
//4.调节AHB总线时钟主频为64MHZ
//5.计时设置通道TIM17_CH1N
//6.计时设置,预分频值为(64-1),计数模式(up),计数周期(1000)
//7.PWM产生通道设置,pluse为500
HAL_TIMEx_PWMN_Start(&htim17,TIM_CHANNEL_1);//开启计时器
31.单通道单次转换:采集光照传感器的值
//1.开启PA4的ADC输入通道
//2.配置串口,设置为异步通信模式
//3.设置串口的比特率(115200),字长(8),校验位(无),停止位(1)
uint32_t value;
while(1)
{
HAL_ADC_Start(&hadc1);//开启ADC转换
HAL_ADC_PollForConversion(&hadc,1000);//等待转换结果
value=HAL_ADC_GetValue(&hadc1);//获取转换结果
HAL_ADC_Stop(&hadc1);//停止转换
HAL_Delay(1000);
}
32.多通道单次转换(在ADC_Settings中开启扫描模式)
//1.配置ADC1_IN1和ADC1_IN4
//2.因为是多通道得再ADC_Settings开启扫描模式
//3.sequencer set to not fully configurable
//4.forward
uint32_t value1;
uint32_t value2;
while(1)
{
HAL_ADC_Start(&hadc1);//开启ADC转换
while(!(ADC1->ISR&(1<<2)));//当EOC为1
value1=HAL_ADC_GetValue(&hadc1);//获取转换结果
while(!(ADC1->ISR&(1<<3)));//当EOS为1
value2=HAL_ADC_GetValue(&hadc1);//获取转换结果
HAL_ADC_Stop(&hadc1);//停止转换
HAL_Delay(1000);
}
33.DMA_ADC单通道采集试验
//1.使能串口
//2.PA4配置为ADC1_IN4
//3.添加DMA搬运通道
//4.使能DMA1通道中断
//5.代码编写
uint16_t buf;
while(1)
{
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&buf,1);
HAL_Delay(1000);
}
34.DMA_ADC多通道采集试验
//1.使能串口
//2.PA1引脚配置为ADC1_IN1,PA4引脚配置为ADC1_IN4
//3.PA8配置为中断
//4.ADC多通道采集得打开扫描模式
//5.使能PA8中断
//6.代码编写
uint16_t buf[2];
//重写按键上升沿中断
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_8)
{
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)buf,2);
}
}
//重写接收数据中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if(hadc == &hadc1)
{
HAL_ADC_Stop_DMA(&hadc1);
printf("key =%d light=%d",buf[0],buf[1]);
memset(buf,0,sizeof(buf));
}
}
//重写printf
int fputc(int ch,FILE *S)
{
while(!(USART1->ISR&(1<<7)));
USART1->TDR=ch;
return ch;
}