c. 实现以时分复用方式在四位7段数码管上一次现实0000-9999数字
由于有共阳极的特性,七段数码管需要使用时分复用的方式进行显示数据。
//选择显示数据位,4位输出数据只有一个置位,其为选择显示的位
void digit_select(int index)
{
BitAction v[4];
int i;
for (i=0; i<4; i++){
//根据index选择显示位
if (index == i){
v = Bit_SET;
}else{
v = Bit_RESET;
}
}
GPIO_WriteBit(GPIOA, GPIO_Pin_11, v[0]);
GPIO_WriteBit(GPIOA, GPIO_Pin_12, v[1]);
GPIO_WriteBit(GPIOC, GPIO_Pin_14, v[2]);
GPIO_WriteBit(GPIOC, GPIO_Pin_15, v[3]);
}
//根据输入数字点亮对应led,共8位,包括小数点以及7段数码管
void digit_show(int digit)
{
int segment, i, base;
BitAction v[8];
switch (digit){
case 0 : segment = 0xc0; break;
case 1 : segment = 0xf9; break;
case 2 : segment = 0xa4; break;
case 3 : segment = 0xb0; break;
case 4 : segment = 0x99; break;
case 5 : segment = 0x92; break;
case 6 : segment = 0x82; break;
case 7 : segment = 0xf8; break;
case 8 : segment = 0x80; break;
case 9 : segment = 0x90; break;
default : segment = 0x86; break;
}
base = 1 << 8;
// 由于数码管为共阳极,所以此处置位为不显示。
for (i=0; i<8; i++){
base >>= 1;
if ((segment & base )== 0){
v = Bit_RESET;
}else{
v = Bit_SET;
}
}
GPIO_WriteBit(GPIOA, GPIO_Pin_0, v[0]);
GPIO_WriteBit(GPIOA, GPIO_Pin_1, v[7]);
GPIO_WriteBit(GPIOA, GPIO_Pin_2, v[6]);
GPIO_WriteBit(GPIOA, GPIO_Pin_3, v[5]);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, v[4]);
GPIO_WriteBit(GPIOA, GPIO_Pin_5, v[3]);
GPIO_WriteBit(GPIOA, GPIO_Pin_6, v[2]);
GPIO_WriteBit(GPIOA, GPIO_Pin_7, v[1]);
}
//控制时分复用,每调用一次显示对应的一位,使用静态变量控制选择位
void display(int digit){
static int index = -1;
int i;
int base = 1000;
index = (index + 1) % 4;
//index=0-3时分别对应从左到右四位
for (i=0; i<index; i++){
base /= 10;
}
digit = (digit / base) % 10;
digit_select(index);
digit_show(digit);
}
|
显示0000-9999的功能调用display函数。由于其需要显示一段时间才能显示完整的四位数字,所以需要循环一段时间。
void ShowData(void* pdata)
{
int value, i;
for (value = 0; value < 10000 ;value += 1111){
for (i = 0; i < 200; i++){
display(value);
Delay_ms(5);
}
if (value == 9999)
value = 0;
}
}
|
下图是显示效果
d. 用两个uC/OS II人物,一个定时读DHT-11数据,一个轮流驱动数码管,一秒一次显示当前温度和湿度。注意处理好两个任务之间的数据共享。
void GetData(void* pdata)
{
uint8_t buf[5];
memset(buf, 0, sizeof(buf));
while (1)
{ //检验数据有效性
if(DHT11_Read_Data(buf) == 1)
{
//温度+湿度
ledValue = buf[2]*100 + buf[0];
}
Delay_ms(1000);
}
}
void ShowData(void* pdata)
{
while(1)
{
//由于传感器数据读取有1s间隔,数值能够稳定显示。
display(ledValue);
Delay_ms(5);
}
}
|
在main函数前面,创建两个优先级为1和2的任务,由于读取数据的任务更重要,所以优先级更高。
int GetData_Task_STK[STK_Size];
int ShowData_Task_STK[STK_Size];
int main(){
GPIO_Configuration();
OSInit();
OS_CPU_SysTickInit();
OSTaskCreate(
GetData,
(void *)0,
(OS_STK *)&GetData_Task_STK[STK_Size-1],
1);
OSTaskCreate(
ShowData,
(void *)0,
(OS_STK *)&ShowData_Task_STK[STK_Size-1],
2
);
OSStart();
return 0;
}
|
下图为显示效果:
表明现在温度是26摄氏度,湿度为54%
|