//头文件
#include<iom16v.h>
#include<macros.h>//SEI()函数_NOP()BIT();
#define uint unsigned int
#define uchar unsigned char
//延时函数
void delay_1ms(void)
{
unsigned int i;
for(i=1;i<(unsigned int)(11.0592*143-2);i++);//定义晶振频率
}
void delay(unsigned int n)//延时毫妙级
{
unsigned int i;
for(i=0;i<n;i++)
delay_1ms();
}
//4位数码管驱动函数
#define SCLK0 (PORTB &=~BIT(0))//定义接线口,需要添加#include<macros.h>才能使用
#define SCLK1 (PORTB |=BIT(0))
#define RCLK0 (PORTB &=~BIT(1))
#define RCLK1 (PORTB |=BIT(1))
#define DAT0 (PORTB &=~BIT(2))
#define DAT1 (PORTB |=BIT(2))
unsigned char number[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//0~9不带小数点,10~19带小数点
unsigned char location[]={0x00,0x01,0x02,0x04,0x08};//0~4
void shumaguan(unsigned char weizhi,unsigned char shuzi)
{ unsigned char i,num; //定义一个无字符串变量
num=number[shuzi];
for(i=0;i<8;i++) //for 循环,循环8次,把一个数变成二进制发送出去
{
SCLK0;
if((num&0x80)==0)
DAT0;
else
DAT1;
num=num<<1;
SCLK1; // 把595频率置高
}
num=location[weizhi];
for(i=0;i<8;i++) //for 循环,循环8次,把一个数变成二进制发送出去
{
SCLK0;// 把595 SCLK频率置低电平
if((num&0x80)==0)
DAT0;
else
DAT1;
num=num<<1;
SCLK1;
}
RCLK0;
_NOP();_NOP();_NOP();_NOP();_NOP(); //延时函数,系统自带
RCLK1;
}
unsigned char encoder_A;//encoder_A需要初始化 encoder_A=(PIND&0x0c)/4;
unsigned angle;//编码器角度变量
void encoder(unsigned int X)//X为编码器线数
{
unsigned char B;
CLI();
B=encoder_A;
encoder_A=(PIND&0x0c)/4;//使用外部中断0,外部中断1
if((B==0 && encoder_A==1)||(B==1 && encoder_A==3)||(B==3 && encoder_A==2)||(B==2 && encoder_A==0))
{
angle=angle+9000/X;
if(angle==36000)angle=0;
}
else if ((B==0 && encoder_A==2)||(B==2 && encoder_A==3)||(B==3 && encoder_A==1)||(B==1 && encoder_A==0))
{
if(angle==0)angle=36000;
angle=angle-9000/X;
}
else ;
SEI();
}
//定义MEGA16接口输入输出
void port_init(void)
{
PORTA = 0xFF;
DDRA = 0x00;
PORTB = 0xFF;
DDRB = 0xFF;
PORTC = 0xFF;
DDRC = 0x00;
PORTD = 0xFF;
DDRD = 0x00;
}
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
MCUCR = 0x05;
GICR = 0xC0;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
init_devices();
encoder_A=(PIND&0x0c)/4;
while(1)
{
shumaguan(1,angle%100/10);
shumaguan(2,angle%1000/100+10);
shumaguan(3,angle%10000/1000);
shumaguan(4,angle/10000);
}
}
#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)
{
encoder(360);
}
#pragma interrupt_handler int1_isr:iv_INT1
void int1_isr(void)
{
encoder(360);
}