目标:四个两位八段(带小数点)数码管,八个位选,八个段选,分为上下两组,每组各四个位选;实现0-9数字循环显示
端口描述:位选1写为1,2,3,4,分别定义在GPIOB口的12,11,10,2端口;段选1写为A,B,C,D,E,F,G,DP,其中A,B,C,D,E,F,定义在GPIOA口的A2,A3,A4,A5,A6,A7;G,DP定义在GPIOB口的B0,B1;位选2写为2-1,2-2,2-3,2-4,分别定义在GPIO口的A11,A12,B9,C13;段选2写为A2,B2,C2,D2,E2,F2,G2,DP2,其中A2,B2,C2,D2,E2,F2,G2,定义在GPIOA口的B5,B4,B3,D3,D2,D1,D0;DP2定义在GPIOB口的A15
我的想法:定义一个table数组,
int table[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
使用GPIO_Write函数写进去,如下定义,但是定义的端口复杂,怎么使用该函数呢?或者别的方式
void GPIO_Write(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin, uint16_t PortVal)
{
assert_param(IS_GPIO_ALL_PERIPH(GPIO));
GPIOx->ODR=PortVal;
}
求解答
如果你想使用GPIO_Write
函数来设置端口的状态,你可以按照以下步骤进行操作:
#include "stm32f10x.h"
GPIO_Init()
函数来进行配置。根据你的描述,你需要配置如下引脚为输出模式:GPIO_InitTypeDef GPIO_InitStructure;
// 设置位选1引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 设置段选1引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 设置段选1引脚的G和DP
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 设置位选2引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_9 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 设置段选2引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 设置段选2引脚的DP
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
其中,GPIO_Pin_x
表示要配置的引脚编号,GPIO_Mode_Out_PP
表示输出模式,GPIO_Speed_50MHz
表示输出速率为50MHz。
GPIO_Write()
函数来操作端口,将需要的位选和段选的值写入相应的引脚。以位选1为例,你可以使用以下代码将相应的位选值写入GPIOB的引脚:
GPIO_Write(GPIOB, GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_2, PortVal);
其中,PortVal
表示位选的值。
根据你的描述,你可以使用一个循环来实现0-9数字的循环显示。你可以定义一个变量displayValue
,每次循环递增,并使用table
数组来获取对应的位选值,然后通过GPIO_Write()
函数来设置位选和段选的引脚状态。例如:
int table[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
int displayValue = 0;
while (1) {
// 设置位选1引脚
GPIO_Write(GPIOB, GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_2, displayValue);
// 设置段选1引脚
GPIO_Write(GPIOA, GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7, table[displayValue]);
// 设置段选1引脚的G和DP
GPIO_Write(GPIOB, GPIO_Pin_0 | GPIO_Pin_1, /* 设置G和DP的值 */);
// 设置位选2引脚
GPIO_Write(GPIOA, GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_9 | GPIO_Pin_13, displayValue);
// 设置段选2引脚
GPIO_Write(GPIOA, GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_0, table[displayValue]);
// 设置段选2引脚的DP
GPIO_Write(GPIOB, GPIO_Pin_15, /* 设置DP的值 */);
displayValue++;
if (displayValue >= 10) {
displayValue = 0;
}
HAL_Delay(1000); // 延时1秒
}
请注意,以上代码中的延时函数HAL_Delay()是一个示例函数,你可能需要根据你的实际情况来选择合适的延时函数。另外,你还需要根据你的硬件连接情况来确定G和DP的值的计算方式。
首先谢谢您的解答,但是我描述的位选2定义在多个端口,而不是只在GPIOA口,这样的话怎么写呢?
@小白熬夜写不出来: 如果您的位选2定义在多个端口而不仅仅是GPIOA口,您可以使用逻辑运算符来组合多个端口。
假设您的位选2定义在GPIOA口(假设为PortA)和GPIOB口(假设为PortB),您可以使用逻辑或运算符(|)将两个端口的值进行组合。
例如,如果您想将PortA的第2位和PortB的第3位作为位选2的值,您可以这样写:
#define BIT_SELECT_2 ((PortA & (1 << 2)) | (PortB & (1 << 3)))
在上面的代码中,(PortA & (1 << 2))
表示获取PortA的第2位的值,(PortB & (1 << 3))
表示获取PortB的第3位的值。然后,使用逻辑或运算符将这两个值进行组合,得到位选2的最终值。
@lanedm: 好的感谢