STM32G0x0系列 入门试验代码整理

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;
}