1、在usr.c中可以看出,LIGHT_OFF的值是1,从usr.c和gpio.h可以看出LIGHT_RED的值是100000111.。
2.用直接地址编程方式,实现红绿蓝三灯轮流闪烁
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
uint32_t mMainLoopCount; //主循环使用的记录主循环次数变量
uint8_t mFlag; //主循环使用的临时变量
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.3)给主函数使用的局部变量赋初值
mMainLoopCount = 0; //主循环使用的记录主循环次数变量
mFlag='R'; //主循环使用的临时变量:蓝灯状态标志
//(1.4)给全局变量赋初值
//(1.5)用户外设模块初始化
// B口9脚(蓝灯,低电平点亮)
//(1.5.1)声明变量
volatile uint32_t* RCC_AHB2; //GPIO的B口时钟使能寄存器地址
volatile uint32_t* gpio_ptr; //GPIO的B口基地址
volatile uint32_t* gpio_mode; //引脚模式寄存器地址=口基地址
volatile uint32_t* gpio_bsrr; //置位/复位寄存器地址
volatile uint32_t* gpio_red_bsrr; //红灯置位/复位寄存器地址
volatile uint32_t* gpio_green_bsrr; //绿灯置位/复位寄存器地址
volatile uint32_t* gpio_blue_bsrr; //蓝灯置位/复位寄存器地址
volatile uint32_t* gpio_red_brr; //红灯复位寄存器地址
volatile uint32_t* gpio_green_brr; //绿灯复位寄存器地址
//(1.5.2)变量赋值
RCC_AHB2=(uint32_t*)0x4002104C; //GPIO的B口时钟使能寄存器地址
gpio_ptr=(uint32_t*)0x48000400; //GPIO的B口基地址
gpio_mode=gpio_ptr; //引脚模式寄存器地址=B口基地址
gpio_red_bsrr = gpio_ptr + 6; //红灯置位/复位寄存器地址
gpio_green_bsrr = gpio_ptr + 6; //绿灯置位/复位寄存器地址
gpio_blue_bsrr = gpio_ptr + 6; //蓝灯置位/复位寄存器地址
gpio_red_brr = gpio_ptr + 10; //红灯复位寄存器地址
gpio_green_brr = gpio_ptr + 10; //绿灯复位寄存器地址
gpio_blue_brr = gpio_ptr + 10; //蓝灯复位寄存器地址
//(1.5.3)GPIO初始化
//(1.5.3.1)使能相应GPIOB的时钟
*RCC_AHB2|=(1<<1); //GPIOB的B口时钟使能
//(1.6)使能模块中断
//(1.7)【不变】开总中断
ENABLE_INTERRUPTS;
for(;;) //for(;;)(开头)
{
if (mMainLoopCount <=6556677) // 控制每次切换的时间间隔
{
mMainLoopCount++; // 清主循环次数
continue;
}
mMainLoopCount=0;
// 切换灯状态
if (mFlag == 'R') // 若灯状态标志为 'R',点亮红灯,熄灭绿灯和蓝灯
{
*gpio_mode &= ~(3<<14); //0b11111111111111110011111111111111;
*gpio_mode |=(1<<14); //0b00000000000000000100000000000000;
*gpio_red_brr |= (1 << 7); // 点亮红灯
*gpio_green_bsrr |=(1 << 8); // 熄灭绿灯
*gpio_blue_bsrr |=(1 << 9); // 熄灭蓝灯
printf("红灯:亮\r\n");
mFlag = 'G'; // 改变状态标志
continue;
}
else if (mFlag == 'G') // 若灯状态标志为 'G',熄灭红灯,点亮绿灯,熄灭蓝灯
{
*gpio_mode &= ~(3<<16); //0b11111111111111001111111111111111;
*gpio_mode |=(1<<16); //0b00000000000000010000000000000000;
*gpio_red_bsrr |= (1 << 7); // 熄灭红灯
*gpio_green_brr |= (1 << 8); // 点亮绿灯
*gpio_blue_bsrr |= (1 << 9); // 熄灭蓝灯
printf("绿灯:亮\r\n");
mFlag = 'B'; // 改变状态标志
continue;
}
else if (mFlag == 'B') // 若灯状态标志为 'B',熄灭红灯和绿灯,点亮蓝灯
{
*gpio_mode &= ~(3<<18); //0b11111111111100111111111111111111;
*gpio_mode |=(1<<18); //0b00000000000001000000000000000000;
*gpio_red_bsrr |= (1 << 7); // 熄灭红灯
*gpio_green_bsrr |= (1 << 8); // 熄灭绿灯
*gpio_blue_brr |= (1 << 9); // 点亮蓝灯
printf("蓝灯:亮\r\n");
mFlag = 'R'; // 改变状态标志
continue;
}
} //for(;;)结尾
}
结果如下:
【用直接地址编程方式,实现红绿蓝三灯轮流闪烁-哔哩哔哩】 https://b23.tv/CEq8Jql
3、用调用构件方式,实现红绿蓝的八种组合轮流闪烁
int main(void)
{
//(1.1)声明main函数使用的局部变量
uint32_t mMainLoopCount; //主循环次数变量
uint8_t mFlag; //灯的状态标志
uint32_t mLightCount; //灯的状态切换次数
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
//(1.3)给主函数使用的局部变量赋初值
mMainLoopCount=0; //主循环次数变量
mFlag='B'; //灯的状态标志
mLightCount=0; //灯的闪烁次数
gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_ON); //初始化蓝灯
gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF); //初始化红灯
gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF); //初始化蓝灯
ENABLE_INTERRUPTS;
for(;;) //for(;;)(开头)
{
mMainLoopCount++;
if (mMainLoopCount<=6444500) continue;
mMainLoopCount=0;
if (mFlag=='B') //判断灯的状态标志
{
mLightCount++;
printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
mFlag='G'; //灯的状态标志
gpio_set(LIGHT_BLUE,LIGHT_ON); //灯“亮”
printf(" LIGHT_BLUE:ON--\n"); //串口输出灯的状态
}
else if(mFlag=='G')
{
mLightCount++;
printf("灯闪烁的次数mLightCount = %d\n",mLightCount);
mFlag='R'; //灯的状态标志
gpio_set(LIGHT_BLUE,LIGHT_OFF); //蓝灯“暗”
gpio_set(LIGHT_GREEN,LIGHT_ON); //绿灯“亮”
printf(" LIGHT_GREEN:ON--\n"); //串口输出灯的状态
}
else if(mFlag=='R')
{
mLightCount++;
printf("灯闪烁的次数mLightCount = %d\n",mLightCount);
mFlag='Y'; //灯的状态标志
gpio_set(LIGHT_GREEN,LIGHT_OFF); //绿灯“暗”
gpio_set(LIGHT_RED,LIGHT_ON); //红灯“亮”
printf(" LIGHT_RED:ON--\n"); //串口输出灯的状态
}
else if(mFlag=='Y')
{
mLightCount++;
printf("灯闪烁的次数mLightCount = %d\n",mLightCount);
mFlag='C'; //灯的状态标志
gpio_set(LIGHT_GREEN,LIGHT_ON); //绿灯“亮”
//gpio_set(LIGHT_RED,LIGHT_ON); //红灯“亮”
printf(" LIGHT_YELLOW:ON--\n"); //串口输出灯的状态
}
else if(mFlag=='C')
{
mLightCount++;
printf("灯闪烁的次数mLightCount = %d\n",mLightCount);
mFlag='P'; //灯的状态标志
gpio_set(LIGHT_RED,LIGHT_OFF); //红灯“暗”
gpio_set(LIGHT_BLUE,LIGHT_ON); //蓝灯“亮”
printf(" LIGHT_CYAN:ON--\n"); //串口输出灯的状态
}
else if(mFlag=='P')
{
mLightCount++;
printf("灯闪烁的次数mLightCount = %d\n",mLightCount);
mFlag='W'; //灯的状态标志
gpio_set(LIGHT_RED,LIGHT_ON); //红灯“亮”
gpio_set(LIGHT_GREEN,LIGHT_OFF); //绿灯“暗”
printf(" LIGHT_PURPLE:ON--\n"); //串口输出灯的状态
}
else if(mFlag=='W')
{
mLightCount++;
printf("灯闪烁的次数mLightCount = %d\n",mLightCount);
mFlag='A'; //灯的状态标志
gpio_set(LIGHT_GREEN,LIGHT_ON); //绿灯“亮”
printf(" LIGHT_WHITE:ON--\n"); //串口输出灯的状态
}
else
{
mLightCount++;
printf("灯闪烁的次数mLightCount = %d\n",mLightCount);
mFlag='B'; //灯的状态标志
gpio_set(LIGHT_RED,LIGHT_OFF); //红灯“暗”
gpio_set(LIGHT_BLUE,LIGHT_OFF); //蓝灯“暗”
gpio_set(LIGHT_GREEN,LIGHT_OFF); //蓝灯“暗”
printf(" LIGHT OFF--\n"); //串口输出灯的状态
}
} //for(;;)结尾
} //main函数(结尾)
结果如下:
【用调用构件方式,实现红绿蓝的八种组合轮流闪烁-哔哩哔哩】 https://b23.tv/FM6JSor