程序来自阿莫论坛的一位,他写的是静态显示,稍微修改一下后如下:
//硬件:ATmega48v,16脚5位段式液晶
//说明:程序采自阿莫论坛坛友,引脚接线不同,所以程序结果不同
//引脚说明:PB0-3接的是四个COM口,PD0-7接SEG0-7 PC0-3接SEG8-11
#include<iom48v.h>
#include<macros.h>
// 设置某个COM IO输出低电平
#define COM0_LOW() do{PORTB &=~BIT(0); DDRB |=BIT(0);}while(0)
#define COM1_LOW() do{PORTB &=~BIT(1); DDRB |= BIT(1);}while(0)
#define COM2_LOW() do{PORTB &=~BIT(2); DDRB |= BIT(2);}while(0)
#define COM3_LOW() do{PORTB &=~BIT(3); DDRB |= BIT(3);}while(0)
// 设置某个COM IO输出高电平
#define COM0_HIGH() do{PORTB |=BIT(0); DDRB |=BIT(0);}while(0)
#define COM1_HIGH() do{PORTB |=BIT(1); DDRB |=BIT(1);}while(0)
#define COM2_HIGH() do{PORTB |=BIT(2); DDRB |=BIT(2);}while(0)
#define COM3_HIGH() do{PORTB |=BIT(3); DDRB |=BIT(3);}while(0)
// 设置所有COM IO输出VDD/2
#define COM_ALL_HALF() do{PORTB &=0XF0; DDRB &=0XF0;}while(0)
// 设置所有COM/SEG IO输出低电平
#define COM_SEG_ALL_LOW() do{PORTB &=0XF0; DDRB |= 0X0F; PORTC &=0XF0 ORTD &=0X00;}while(0)
// 定义SEG端口
#define SEG_LOAD(x) do{PORTD = (x); PORTC |= ((x) >> 8) &0X0F;}while(0)
#define uchar unsigned char
#define uint unsigned int
typedef uint u16;
typedef uchar u8;
uchar number[] = {0x7E, 0x0A, 0xBC, 0x9E, 0xCA, 0xD6, 0xF6, 0x0E, 0xFE, 0xDE}; //定义数组
u16 frame[4];// LCD帧缓存
uchar Turn = 0, COM = 0;
/********************************************************延时函数**********************************************************/
void delayms(uint ms)
{
uint i;
for (; ms>0; ms--)
for (i=1000; i>0; i--);
}
/********************************************************液晶驱动**********************************************************/
void yjdis(u8 *x)
{
u8 i, Show_Char;
frame[0] = 0;
frame[1] = 0;
frame[2] = 0;
frame[3] = 0;
for (i=0; i<6; i++)
{
if((*(x + i) < 0x3A) && (*(x + i) > 0x2F))
Show_Char = number[*(x + i) - 0x30];
if(Show_Char & 0x01) frame[0] |= 0x0001 << (i << 1);
if(Show_Char & 0x10) frame[0] |= 0x0002 << (i << 1);
if(Show_Char & 0x02) frame[1] |= 0x0001 << (i << 1);
if(Show_Char & 0x20) frame[1] |= 0x0002 << (i << 1);
if(Show_Char & 0x04) frame[2] |= 0x0001 << (i << 1);
if(Show_Char & 0x40) frame[2] |= 0x0002 << (i << 1);
if(Show_Char & 0x08) frame[3] |= 0x0001 << (i << 1);
if(Show_Char & 0x80) frame[3] |= 0x0002 << (i << 1);
}
}
/********************************************************中断部分 产生脉冲**********************************************************/
#pragma interrupt_handler t0:15 // 捕获中断 定时器0比较匹配A
void t0()
{
TIFR0 &= ~0x02;
if(Turn++ == 0)
{
SEG_LOAD(frame[COM]);
COM_ALL_HALF();
if(COM == 0) {COM0_LOW();}
if(COM == 1) {COM1_LOW();}
if(COM == 2) {COM2_LOW();}
if(COM == 3) {COM3_LOW();}
}
else
{
Turn = 0;
SEG_LOAD(~frame[COM]);
COM_ALL_HALF();
if(COM == 0) {COM0_HIGH();}
if(COM == 1) {COM1_HIGH();}
if(COM == 2) {COM2_HIGH();}
if(COM == 3) {COM3_HIGH();}
if(++COM > 3) COM = 0;
}
}
#pragma interrupt_handler t0yc:17 // 定时器0溢出中断
void t0yc()
{
TIFR0 &= ~0x01;
COM_SEG_ALL_LOW();
}
/********************************************************端口初始化和寄存器初始化**********************************************************/
void t0init() // Timer0快速PWM初始化
{
DDRB |= 0X0F; // COM0~3
DDRD |= 0xfF; // SEG0~7
TCCR0A = 0x03; // 配置定时器工作在快速PWM模式,8分频
TCCR0B = 0x02;
OCR0A = 0x9F; // 设置捕捉比较初值,0x3f
TIMSK0 |= 0x03; // 开捕获中断,溢出中断
SREG |= 0x80; // 开总中断
}
/*******************************************************主函数*********************************************************/
void main()
{
t0init(); //定时器0快速PWM初始化及IO口初始化
yjdis("3210");
while(1);
}
静态显示没有问题,但是想做个钟来着,所以尝试了下动态显示,也就是将四位拆开,
//硬件:ATmega48v,16脚5位段式液晶
//说明:程序采自阿莫论坛坛友,引脚接线不同,所以程序结果不同
//引脚说明:PB0-3接的是四个COM口,PD0-7接SEG0-7 PC0-3接SEG8-11
#include<iom48v.h>
#include<macros.h>
// 设置某个COM IO输出低电平
#define COM0_LOW() do{PORTB &=~BIT(0); DDRB |=BIT(0);}while(0)
#define COM1_LOW() do{PORTB &=~BIT(1); DDRB |= BIT(1);}while(0)
#define COM2_LOW() do{PORTB &=~BIT(2); DDRB |= BIT(2);}while(0)
#define COM3_LOW() do{PORTB &=~BIT(3); DDRB |= BIT(3);}while(0)
// 设置某个COM IO输出高电平
#define COM0_HIGH() do{PORTB |=BIT(0); DDRB |=BIT(0);}while(0)
#define COM1_HIGH() do{PORTB |=BIT(1); DDRB |=BIT(1);}while(0)
#define COM2_HIGH() do{PORTB |=BIT(2); DDRB |=BIT(2);}while(0)
#define COM3_HIGH() do{PORTB |=BIT(3); DDRB |=BIT(3);}while(0)
// 设置所有COM IO输出VDD/2
#define COM_ALL_HALF() do{PORTB &=0XF0; DDRB &=0XF0;}while(0)
// 设置所有COM/SEG IO输出低电平
#define COM_SEG_ALL_LOW() do{PORTB &=0XF0; DDRB |= 0X0F; PORTC &=0XF0 ORTD &=0X00;}while(0)
// 定义SEG端口
#define SEG_LOAD(x) do{PORTD = (x); PORTC |= ((x) >> 8) &0X0F;}while(0)
#define uchar unsigned char
#define uint unsigned int
typedef uint u16;
typedef uchar u8;
uchar number[] = {0x7E, 0x0A, 0xBC, 0x9E, 0xCA, 0xD6, 0xF6, 0x0E, 0xFE, 0xDE}; //定义数组
u16 frame[4];// LCD帧缓存
uchar Turn = 0, COM = 0;
/********************************************************延时函数**********************************************************/
void delayms(uint ms)
{
uint i;
for (; ms>0; ms--)
for (i=1000; i>0; i--);
}
/********************************************************液晶驱动**********************************************************/
void yjdis(u8 *x,uchar i)
{
u8 Show_Char;
frame[0] = 0;
frame[1] = 0;
frame[2] = 0;
frame[3] = 0;
{
if((*(x + i) < 0x3A) && (*(x + i) > 0x2F))
Show_Char = number[*(x + i) - 0x30];
if(Show_Char & 0x01) frame[0] |= 0x0001 << (i << 1);
if(Show_Char & 0x10) frame[0] |= 0x0002 << (i << 1);
if(Show_Char & 0x02) frame[1] |= 0x0001 << (i << 1);
if(Show_Char & 0x20) frame[1] |= 0x0002 << (i << 1);
if(Show_Char & 0x04) frame[2] |= 0x0001 << (i << 1);
if(Show_Char & 0x40) frame[2] |= 0x0002 << (i << 1);
if(Show_Char & 0x08) frame[3] |= 0x0001 << (i << 1);
if(Show_Char & 0x80) frame[3] |= 0x0002 << (i << 1);
}
}
/********************************************************中断部分 产生脉冲**********************************************************/
#pragma interrupt_handler t0:15 // 捕获中断 定时器0比较匹配A
void t0()
{
TIFR0 &= ~0x02;
if(Turn++ == 0)
{
SEG_LOAD(frame[COM]);
COM_ALL_HALF();
if(COM == 0) {COM0_LOW();}
if(COM == 1) {COM1_LOW();}
if(COM == 2) {COM2_LOW();}
if(COM == 3) {COM3_LOW();}
}
else
{
Turn = 0;
SEG_LOAD(~frame[COM]);
COM_ALL_HALF();
if(COM == 0) {COM0_HIGH();}
if(COM == 1) {COM1_HIGH();}
if(COM == 2) {COM2_HIGH();}
if(COM == 3) {COM3_HIGH();}
if(++COM > 3) COM = 0;
}
}
#pragma interrupt_handler t0yc:17 // 定时器0溢出中断
void t0yc()
{
TIFR0 &= ~0x01;
COM_SEG_ALL_LOW();
}
/********************************************************端口初始化和寄存器初始化**********************************************************/
void t0init() // Timer0快速PWM初始化
{
DDRB |= 0X0F; // COM0~3
DDRD |= 0xfF; // SEG0~7
TCCR0A = 0x03; // 配置定时器工作在快速PWM模式,8分频
TCCR0B = 0x02;
OCR0A = 0x9F; // 设置捕捉比较初值,0x3f
TIMSK0 |= 0x03; // 开捕获中断,溢出中断
SREG |= 0x80; // 开总中断
}
/*******************************************************主函数*********************************************************/
void main()
{
t0init(); //定时器0快速PWM初始化及IO口初始化
while(1)
{
yjdis(" 2",3);//前面一个参数选择数组中的第几个,后一个参数是第几位显示,
//注意,当参数二为123时,前面要加入多个空格,格入如下:
//(" 2",1)(" 2",2)(" 2",3)
delayms(5);
//yjdis(" 1",1);delayms(5);
// yjdis(" 2",2);delayms(1);
//yjdis(" 3",3);delayms(1);
}
}
显示两个勉强能看清,三个一起扫描的时候就不行了。
有朋宇有能用的程序共享吗,
或者在这程序上修改下
|