这次是竞赛板的LED部分。
SN74HC573ADWR是锁存器,LED1-8由PC的高八位控制PC8-PC15.
其中还有PD2作为锁存器的“开关”。
在操作LED时必须要打开锁存器,这时要把PD2置1,在操作完LED后要记得把PD2置0,这样做是因为LCD也会用到PC口,会造成冲突,解决方案会在之后提出。
先是按照上一次配置好基本的东西。
其次是配置PC端的高八位,设置成GPIO_Output模式,它默认是推挽输出,不用做什么改变。如图所示
在这里点开某一个引脚后,会出现配置信息。最下面有个User Label,可以自己定义,这里我定义它为LED1,在进入工程后可以在main.h中找到相关的define,就是将这一个引脚的端口和引脚等信息进行define,便于阅读与移植。
/* Private defines -----------------------------------------------------------*/
#define LED1_Pin GPIO_PIN_8
#define LED1_GPIO_Port GPIOC
配置完成后就直接生成工程就行了。
打开工程后就是这样,不用修改。
上面有BEGIN和END的语句,自己写的内容,比如函数,还有一些define、变量之类的东西最好都写在BEGIN和END语句中间,不写在这中间的话,如果想要修改配置再次使用CubeMx生成工程时,不写在这中间的内容都会擦除,写在BEGIN和END语句中间的内容不会被抹去。
其次,需要点开魔术棒,点开Debug,生成的工程,由于刚开始选择的是Serial Wire,所以这里默认会是STLink,但是比赛需要用的是CMSIS-DAP Debugger这个下载器。
点开旁白的Setting,可以选择Max Clock为10MHz,也可以不修改,这个没啥影响。
点开Flash Download,勾选Reset and Run,不然会报错。有时候可能flah也会没有,这时候需要自己添加。如果MDK中没有这个flash,可以在STM32G4的芯片包里找到,然后复制到MDK的flash就可以添加了。
下面就是正式编写程序了。
相对应的函数都可以在对应的头文件中找到。
主要应用的函数就是下面三个
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
就是读取对应的引脚的状态。多用在输入的时候。
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
就是给对应的引脚写状态。
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
就是对应引脚的状态翻转。
在工程中,延时函数是已经定义好的。
__weak void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait)
{
}
}
可以直接在main函数里引用。
下面就可以点亮LED与流水灯了\
下面就是使用的宏定义的PC8,即LED1_PIN。
while (1)
{
HAL_GPIO_WritePin(GPIOC,LED1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOC,LED1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
上述内容也可以写成(换个引脚,换成PC9)
while (1)
{
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
也可以使用宏定义,像下面这种(可以定义在gpio.h中)
#define LED2_TOGGLE() HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);\
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);\
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
在多行的宏定义的时候,要在每一行最后加一个\,且后面不能有任何字符,否则会产生错误。、
然后直接在main函数里调用即可。
while (1)
{
LED2_TOGGLE();
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}