给出gpio_set(LIGHT_RED,LIGHT_OFF);语句中,LIGHT_RED和LIGHT_OFF的值是多少?贴出每一步的查找截图。
(1)这种全大写的变量名一般是宏变量,其一般定义在头文件中
(2)在includes.h中没有发现目标变量,继续查询user.h
(3)在user.h中发现LIGHT_OFF值为1,LIGHT_RED值由PTB_NUM或运算7得出,继续在头文件中查找PTB_NUM的值
(4)在gpio.h中发现PTB_NUM的值为1左移8位,得LIGHT_RED的值为0b0000 0001 0000 0111,即263
用直接地址编程方式,实现红绿蓝三灯轮流闪烁。
#define GLOBLE_VAR
#include "includes.h" //包含总头文件
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
uint32_t mMainLoopCount; //主循环使用的记录主循环次数变量
uint8_t mFlag; //主循环使用的临时变量
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.5)用户外设模块初始化
volatile uint32_t* gpio_ptr; //GPIO的B口基地址
volatile uint32_t* gpio_mode; //引脚模式寄存器地址=口基地址
gpio_ptr=(uint32_t*)0x48000400; //GPIO的B口基地址
gpio_mode=gpio_ptr; //引脚模式寄存器地址=口基地址
//(1.5.3)GPIO初始化
*gpio_mode &= ~(0b111111<<14);//0b11111111111100000011111111111111
*gpio_mode |=(0b101010<<14);//0b00000000000001010100000000000000
//这样做的目的在于更改了D19~D14两位的值,而不改变其他位的值,不这样的话,可能把不需要改变的位也改变了!
//(1.7)【不变】开总中断
ENABLE_INTERRUPTS;
//(1)======启动部分(结尾)==========================================
//(2)======主循环部分(开头)=========================================
for(uint8_t mStatu = 0/*灯状态变量,0红1绿2蓝3红4绿以此类推*/;;) //for(;;)(开头)
{
//(2.1)主循环次数+1,并判断是否小于特定常数
mMainLoopCount++; //+1
if (mMainLoopCount<=6556677) continue; //如果小于特定常数,继续循环
mMainLoopCount=0; //清主循环次数
//(2.2)主循环次数超过特定常数,灯状态进行切换(这样灯会闪烁)
*gpio_mode &= ~(0b111111<<14);//所有灯状态归零,灯全灭
if (mStatu % 3 == 0)
{
*gpio_mode|=(0b000010<<14);//红灯“亮”
printf("红灯亮\r\n");//串口输出灯的状态
}
else if (mStatu % 3 == 1)
{
*gpio_mode|=(0b001000<<14);//绿灯“亮”
printf("绿灯亮\r\n");//串口输出灯的状态
}
else
{
*gpio_mode|=(0b100000<<14);//蓝灯“亮”
printf("蓝灯亮\r\n");//串口输出灯的状态
}
mStatu++;//灯状态变量后推一位
} //for(;;)结尾
//(2)======主循环部分(结尾)========================================
}
实验现象:
用调用构件方式,实现红绿蓝的八种组合轮流闪烁。
#define GLOBLE_VAR
#include "includes.h" //包含总头文件
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
uint32_t mMainLoopCount; //主循环次数变量
uint32_t mLightCount; //灯的状态切换次数
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.3)给主函数使用的局部变量赋初值
mMainLoopCount=0; //主循环次数变量
mLightCount=0; //灯的闪烁次数
//(1.5)用户外设模块初始化
gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_ON);//初始化红灯
gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_ON);//初始化绿灯
gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_ON);//初始化蓝灯
//(1.7)【不变】开总中断
ENABLE_INTERRUPTS;
//(1)======启动部分(结尾)==========================================
//(2)======主循环部分(开头)========================================
for(uint8_t mStatu = 0/*灯状态变量,0红1绿2蓝3红4绿以此类推*/;;) //for(;;)(开头)
{
//(2.1)主循环次数变量+1
mMainLoopCount++;
//(2.2)未达到主循环次数设定值,继续循环
if (mMainLoopCount<=12888999) continue;
//(2.3)达到主循环次数设定值,执行下列语句,进行灯的亮暗处理
//(2.3.1)清除循环次数变量
mMainLoopCount=0;
mLightCount++;
printf("灯的闪烁次数 mLightCount = %d,",mLightCount);
gpio_set(LIGHT_RED,LIGHT_OFF); //红灯“暗”
gpio_set(LIGHT_GREEN,LIGHT_OFF); //绿灯“暗”
gpio_set(LIGHT_BLUE,LIGHT_OFF); //蓝灯“暗”
if (mStatu % 8 < 4)
{
gpio_set(LIGHT_RED,LIGHT_ON); //红灯“亮”
printf(" 红灯亮,"); //串口输出灯的状态
}
if (mStatu % 4 < 2)
{
gpio_set(LIGHT_GREEN,LIGHT_ON); //绿灯“亮”
printf(" 绿灯亮,"); //串口输出灯的状态
}
if (mStatu % 2 < 1)
{
gpio_set(LIGHT_BLUE,LIGHT_ON); //蓝灯“亮”
printf(" 蓝灯亮,"); //串口输出灯的状态
}
printf("\n");
mStatu++;//灯状态变量后推一位
} //for(;;)结尾
//(2)======主循环部分(结尾)========================================
} //main函数(结尾)
实验现象: