中微单片机IO口复用方式控制LED数码管

中微单片机IO口复用方式控制LED数码管

CMS8H1213 CMS8H121X是中微半导体基于RISC内核推出的高精度测量SoC, 应用于人体秤、厨房秤、气泵等高精度测量领域。主频8MHz/16MHz;工作电压2.0V至4.5V;提供8KB ROM,344B RAM ,128B EEPROM ;内置24位高精度Sigma-Delta ADC,支持1路差分输入,增益可选2 、4 、12 、16 、48、64 、128 、384 ,输出速率可选:10Hz~10.4KHz;有效分辨率最高可达20.0位,带内短开关和系统斩波开关,PGA直通SAR ADC,集成温度传感器;内置多通道12-bit SAR ADC;支持硬件LED驱动,最多支持8COM x 8 SEG ; 支持1个UART; 支持2路定时器; 可工作在-40℃至85℃;提供SOP16、SSOP24的封装

为了节省IO资源,我们采用7个IO控制40段数码。数码管采用单个0603贴片LED组成。
原理图:

RB6 用的是RA7

/*扫描是在定时器0中断时运行,刷新率500以上时,运算工作很繁重,为了减轻MCU压力,
做了两组缓冲,先把显示内容拆分需要直接输出的内容,0.1秒拆分一次就可以了。
IO复时LED正极需要高电平IO才输出,低电平IO需要配置为输入,否则会有影响。
*/
const uint8_t	SegTab[]={
1,2,3,4,5,6,  //RB0 = 1
0,2,3,4,5,6,	//RB1
0,1,3,4,5,6,  //RB2
0,1,2,4,5,6,   //RB3  bat OO
//RB4
0,   //card
1,   //moto
2,   //bike
3,   //ball  
5,   //bat1
6,   //bat2
//RB5
0,   //bat3
1,   //bar
2,	//psi
3,   //KPa
4,   // kg/cm
6,   //nc
//RB6 = 1
0,   //key down
1,   //sos
2,   //up
3,    //switch
4,
5

};
//按a=0,b=1,c=2,d=3,e=4,f=5,g=6,h=7的共阴极,其显示0-9的数值如下
const uint8_t SEG_DIGIT_VALUE[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
uint8_t	DisBuf[5]={0};   //显示缓冲
uint8_t	SegBuf[6]={0};   //输出缓冲
volatile	uint8_t	Dig_Cnt;
volatile	uint8_t	Hpin,Lpin;
volatile	uint8_t	RegCnt=0;


/***********************************************
函数名称:Init_Timer
函数功能:端口初始化
入口参数:period_ms
出口参数:无
备注:TMR0溢出产生中断;选择MODE_FsysDIV4模式下,无关外部IO变化
************************************************/
void Init_Timer0(TIMER0_MODE_E mode, T0CKL_SINGAL_TREND_E trend, TMR0_PRE_DIV preDiv)
{
	if(mode == MODE_T0CKL_PIN)
	{
		TRISA2 = 1;
	}
	
	OPTION_REG &= 0x00;
	T0CS = mode;
	T0SE = trend;
	
	PSA = 0;
	
	OPTION_REG |= preDiv;
	
	T0IF = 0;
	T0IE = 1;
}
/***********************************************
函数名称:Init_System
函数功能:系统初始化
入口参数:无
出口参数:无
备注:
************************************************/
void Init_System(void)
{
	GIE = 1;
	PEIE = 1;				
	OSCCON |= 0x70;		//Fsys=Fosc
}
/***********************************************
函数名称:GPIO_Init
函数功能:初始化GPIO配置 
入口参数:无
出口参数:无
备注:
************************************************/
void GPIO_Init(void)
{
	PORTA = 0x7F;   //	
	TRISA = 0x7f;   //方向控制 1:输入 0:输出
	WPUA  = 0x7F;	//上拉		
	PAPI  = 0x2f;   //拉电流	
	
	PORTB = 0x7F;   //	
	TRISB = 0x00;	//方向控制 1:输入 0:输出
	PBPI = 0x55;    //拉电流控制 15ma
	SEGENB = 0xff;	//拉电流使能
	COMENB = 0xff;	//灌电流控制 164ma
	
	PORTC = 0;
	TRISC = 0x00;   //输出
	/*PORTB0 上拉输入 Enable Interrupt*/	
//	WPDA0 = 1;		//下拉

	IOCA  = 0X01;	//电平变中断
	RACIF = 0;	//中断标志清零	
	RACIE = 1;	//PA电平变化中断		
}
/***********************************************************
main主函数
***********************************************************/
void main(void)
{
	u32	temp32;
	
	GPIO_Init();
	Init_System();

	DataIni();
	Init_Timer0(MODE_FsysDIV4, T0CKL_LowToHigh,TMR0_PRE_DIV4);	//8M/4/2 = 1M  256 / 1M = 256us
	while(1)
	{
		SwapBuf();  //空间转换
	//应用程序
	}

/****************************
笔段空间转换
*****************************/
void	SwapBuf(void)
{
	u8	i,j;
	u8	da,n,m;
	n=0;
	do
	{
		j = n /6;
		da = 0;
		for(i=0;i<6;i++)
		{
			m = n >> 3;
			if(DisBuf[m] & (1 << (n % 8)))
				da |= (1 << SegTab[ j* 6 + i]);
			n++;
		}
		SegBuf[j] = da;

	}while(n<42);
}
/*******************************************************
函数名称:ISR
函数功能:中断服务函数
入口参数:无
出口参数:无
备注:
************************************************/
void interrupt ISR()
{
	//*************数码管扫描*********************************
	if(T0IF)
	{
		Lpin = SegBuf[Hpin];  //加载笔段
		PORTB = 0xff;
		TRISA7 = 1; //input	
		TRISB = 0xff;
		RA7 = 1;
		if(Hpin == 6 )
		{	TRISA7 = 0; //out 
			RA7 = 0;    //行选
		} 
		else
		{	
			PORTB = ~(1<<Hpin);  //ROW LOW
		} 	
		if(Lpin & 0x40)  //列选
		{	RA7 = 1;	
			TRISA7 = 0; 
		}//out		
		TRISB = ~((1<<Hpin) | Lpin);
		Hpin++;
		if(Hpin > 6 )
		{
			 Hpin = 0; 
		}				
		T0IF = 0;	
	}
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用中微电子单片机的3个IO控制6个LED灯的程序示例,同样使用了第一种方式,即使用74HC238译码器: ```c #include "HT66F70A.h" #define LED_PORT P13 #define ADDR_PORT P14 void GPIO_Config(void); void Delay(uint32_t count); int main(void) { GPIO_Config(); while (1) { // 点亮第1个LED灯 PORT_Write(ADDR_PORT, 0x01); PORT_Write(LED_PORT, 0x01); Delay(100000); // 点亮第2个LED灯 PORT_Write(ADDR_PORT, 0x02); PORT_Write(LED_PORT, 0x02); Delay(100000); // 点亮第3个LED灯 PORT_Write(ADDR_PORT, 0x04); PORT_Write(LED_PORT, 0x04); Delay(100000); // 点亮第4个LED灯 PORT_Write(ADDR_PORT, 0x01); PORT_Write(LED_PORT, 0x08); Delay(100000); // 点亮第5个LED灯 PORT_Write(ADDR_PORT, 0x02); PORT_Write(LED_PORT, 0x10); Delay(100000); // 点亮第6个LED灯 PORT_Write(ADDR_PORT, 0x04); PORT_Write(LED_PORT, 0x20); Delay(100000); } } void GPIO_Config(void) { PORT_InitTypeDef PORT_InitStructure; // 配置LED引脚为推挽输出 PORT_InitStructure.PORT_Pin = 0x3F; // P13的6位和P14的3位 PORT_InitStructure.PORT_Mode = PORT_Mode_OUT; PORT_InitStructure.PORT_OutType = PORT_OutType_PP; PORT_InitStructure.PORT_Speed = PORT_Speed_10MHz; PORT_Init(LED_PORT, &PORT_InitStructure); // 配置地址引脚为推挽输出 PORT_InitStructure.PORT_Pin = 0x07; // P14的3位 PORT_InitStructure.PORT_Mode = PORT_Mode_OUT; PORT_InitStructure.PORT_OutType = PORT_OutType_PP; PORT_InitStructure.PORT_Speed = PORT_Speed_10MHz; PORT_Init(ADDR_PORT, &PORT_InitStructure); } void Delay(uint32_t count) { for(uint32_t i = 0; i < count; i++); } ``` 需要注意的是,此程序只是一个示例,具体的引脚配置和控制方式需要根据实际情况进行修改。同时,需要根据实际使用的译码器型号,确定地址引脚的数量和连接方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fpd_led

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值