参加2023年电赛后,到现在上班一年多,长达两年时间内,几乎没有再碰过单片机,由于现在工作中需要接触到一些代码,先退回来复习下32单片机。
本人在此做一件事情,傻瓜式代码,让代码足够简洁,足够规范,让你复制我的代码百分百能够使用。此账号仅作为分享本人复习过程中记录使用,如果无法使用,或者或者有优化的地方,欢迎留言,看到后第一时间给予回复。有空会将2023激光打靶代码开源出来。
在使用本程序的时候,默认你看过江科大的32工程的视频。(没看过的先回去恶补下)
LED.C
#include "stm32f10x.h"
/**
* @brief LED控制函数
* @param GPIOx
* @arg 在stm32f103C8T6这款单片机中,外设GPIO只有A,B,C三个
* @param GPIO_PIN_x
* @arg GPIO只有16个,范围1-16
* @param Power
* @arg 1开启,0关闭
* @retval 无
*/
void LED_Optino(GPIO_TypeDef* GPIOx,uint16_t GPIO_PIN_x, uint8_t Power)
{
if(GPIOx == GPIOA)//判断输入的GPIO开启对应的时钟
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOA的时钟
}else if(GPIOx == GPIOB)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启GPIOB的时钟
}else if(GPIOx == GPIOC)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//开启GPIOC的时钟
}
GPIO_InitTypeDef GPIO_InitStructure;//IO初始化结构体
//IO结构体的初始化
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_x;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOx,&GPIO_InitStructure);
//LED开关
if(Power == 1){GPIO_WriteBit(GPIOx,GPIO_PIN_x,Bit_RESET);}
else {GPIO_WriteBit(GPIOx,GPIO_PIN_x,Bit_SET);}
}
LED.h
#ifndef __LED_H
#define __LED_H
void LED_Optino(GPIO_TypeDef* GPIOx,uint16_t GPIO_PIN_x, uint8_t Power);
#endif
main.c
#include "stm32f10x.h" // Device header
#include "LED.h"
int main(void)
{
while(1)
{
LED_Optino(GPIOC,GPIO_Pin_13,0);
}
}
流水灯笨蛋方法,自己定义需要点亮的灯,优势是比较简单,缺点是下一次想更换端口的时候,都需要更改一次源码。这里可以用GPIO_Write一次控制16个GPIO引脚来实现流水灯的方式。只不过需要再重写一次代码有点麻烦这里就不写了。
void waterfall_light(void)
{
LED_Optino(GPIOB, GPIO_Pin_12, 1);
LED_Optino(GPIOB, GPIO_Pin_13, 0);
LED_Optino(GPIOB, GPIO_Pin_14, 0);
LED_Optino(GPIOB, GPIO_Pin_15, 0);
Delay_ms(500);
LED_Optino(GPIOB, GPIO_Pin_12, 0);
LED_Optino(GPIOB, GPIO_Pin_13, 1);
LED_Optino(GPIOB, GPIO_Pin_14, 0);
LED_Optino(GPIOB, GPIO_Pin_15, 0);
Delay_ms(500);
LED_Optino(GPIOB, GPIO_Pin_12, 0);
LED_Optino(GPIOB, GPIO_Pin_13, 0);
LED_Optino(GPIOB, GPIO_Pin_14, 1);
LED_Optino(GPIOB, GPIO_Pin_15, 0);
Delay_ms(500);
LED_Optino(GPIOB, GPIO_Pin_12, 0);
LED_Optino(GPIOB, GPIO_Pin_13, 0);
LED_Optino(GPIOB, GPIO_Pin_14, 0);
LED_Optino(GPIOB, GPIO_Pin_15, 1);
Delay_ms(500);
}
高级一点的办法,由于PIN脚是一个uint16_t的变量,查看GPIO_PIN_的引脚定义,可以看到,每一位表示一个PIn脚,在手册中也可以看到端口端口输出数据寄存器(GPIOx_ODR)的高16位置为保留状态,低16位用于控制对应GPIO引脚,在得到参数2的最高位和最低位,就可以指定IO口进行流水灯操作了。
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */
#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */
#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */
#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */
#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */
#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */
/**
* @brief 找到最高位
* @param data
* @arg 传入的PIN脚
* @retval
*/
int16_t find_end(uint16_t data)
{
if( data == 0) return -1;//没有1的存在
uint16_t pos = 15;
while((data & (1 << pos)) == 0)
{
pos--;
}
return pos;
}
/**
* @brief 找到最低位
* @param data
* @arg 传入的PIN脚
* @retval
*/
int16_t find_Start(uint16_t data)
{
if( data == 0) return -1;//没有1的存在
uint16_t pos = 0;
while((data & (1 << pos)) == 0)
{
pos++;
}
return pos;
}
void waterfall_light_advanced(GPIO_TypeDef* GPIOx,uint16_t GPIO_PIN_x, uint8_t direct)
{
uint16_t end, start;
end = find_end(GPIO_PIN_x);
start = find_Start(GPIO_PIN_x);
if(direct)
{
for(uint16_t i = start; i <= end; i++) //从低到高
{
LED_Optino(GPIOx,1<= start; i--)//从高到低
{
LED_Optino(GPIOx,1<
main.c
#include "stm32f10x.h" // Device header
#include "LED.h"
int main(void)
{
while(1)
{
waterfall_light_advanced(GPIOA,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11,0);
waterfall_light_advanced(GPIOA,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11,1);
}
}
在此呼吁朋友们注意代码的通用性,尽量将代码编写成不用修改源码,只用改变不同的参数,就可以实现不同的一个功能,这样不仅仅是对自己是一个很大的提升,也是为了在比赛,工作中更好的配置。
本人只学过江科大的51,32代码基础比较薄弱,如有错误,请大佬指出,定第一时间修改。(代码全部经过本人测试可以使用,如果需要整个工程,请留下邮箱)