试验目录
- 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置为00GPIOB->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置为00GPIOB->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 */
}//mainwhile (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为500HAL_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为1value1=HAL_ADC_GetValue(&hadc1);//获取转换结果while(!(ADC1->ISR&(1<<3)));//当EOS为1value2=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;
}