|
发表于 2005-1-22 18:42:33
|
显示全部楼层
我写的程序哦
使用的是3*2扫描式键盘
显示用的是595驱动的4个数码管,B口先送位码 D口再送段码
/******************************************************************************
程序名称:电机驱动程序
运行平台:ATMaga8 4m晶振
程序版本:2.0
程序说明:通过按键 或A/D输入来调节pw波
pc0-pc4 对应 r3-r1(pc3 作为ad输入)
pwm 波通过pc5输出
当a/d输入有效时,键盘自动屏蔽
键盘说明
[rest] [+] [-]
[none] [none] [none ]
作者:Gorgon Meducer
最后修改:Gorgon Meducer
修改时间:2004年12月29日
******************************************************************************/
#include <iom8v.h>
#include <macros.h>
#pragma interrupt_handler Timer1_ovf:9
#pragma interrupt_handler Adc_isr:15 //
const char DispCode[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,
0xee,0x3e,0x9c,0x7a,0x9e,0x8e}; //数码管译码表
const char DispBit[] = {0b11101111,0b11011111,0b10111111,0b01111111};//数码管初始位值
unsigned char Mark_Line=0x80;
//定时器延时
unsigned int Timer_Count_End=0;
unsigned int Timer_Count=0;
//unsigned char PressKey_Per_n_Timer_Ovf=0; //定义按键时间计数器
unsigned char Press_Keys=0; //按键代码
/***************************************************************************/
void Port_init(void);
void Timer0_init(void);
void Timer1_init(void);
void Timer1_ovf(void);
void Hardware_init(void);
void Delay_ms(unsigned int delay_time);
void Key_Press_Scan(void);
void adc_init(void);
void Display_Message(unsigned char Where,unsigned char Number,unsigned char delays);
/***************************************************************************/
/***************************************************************************
端口初始化
****************************************************************************/
void Port_init(void)
{
//定义c为输入
DDRC =0b11111111;
PORTC=0b11111111;
DDRC =0b00100000; //PC5用来输出pw波
//定义B口为输出,用于显示数据
DDRB=0xff;
PORTB=0xff;
//定义D口为输出,用于显示数据
DDRD=0xff;
PORTD=0x00;
}
/***************************************************************************
定时器0初始化
****************************************************************************/
//TIMER0 initialize - prescale:1
// desired value: 20KHz
// actual value: 20.000KHz (0.0%)
//定时器0用来产生PW波
void Timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x38; //set count
TCCR0 = 0x01; //start timer
}
/***************************************************************************
定时器1初始化
****************************************************************************/
//定时器1主要用来做精确延时
void Timer1_init(void)
{
//定时器1部分
TCNT1H = 0xE0;
TCNT1L = 0xC0;
TCCR1B = 0x01; //1分频,定时1ms
}
/***************************************************************************
A/D初始化
****************************************************************************/
void adc_init(void)
{
ADCSRA =0X00; //关闭AD
ADMUX = 0b00100011; //选择外部参考电源 ADC3 左对齐
ACSR = (1<<ACD); //关闭模拟比较器
ADCSRA = 0b10011110;//中断允许 64分频
}
/***************************************************************************
A/D中断处理
****************************************************************************/
void Adc_isr(void)
{
Mark_Line=ADCH; //读取高位数据(左对齐)
ADMUX = 0b00100011; //选择外部参考电源 ADC3 左对齐
ADCSRA |=(1<<ADSC); //启动AD转换
}
/***************************************************************************
定时器1中断处理程序
****************************************************************************/
void Timer1_ovf(void) //1ms中断程序,检测主程序标志
{
TCNT1H = 0xE0;
TCNT1L = 0xC0; //复位1ms记数器
if (Timer_Count>0)
{
Timer_Count++;
}
if (Press_Keys==2)
{
Mark_Line++;
if (Mark_Line>0xff)
{
Mark_Line=0x00;
}
}
if (Press_Keys==3)
{
Mark_Line--;
if (Mark_Line<0x01)
{
Mark_Line=0xff;
}
}
if (Press_Keys==1)
{
Mark_Line=0x80; //复位
}
if (TCNT0>Mark_Line)
{
//驱动电机
PORTC |= 0b00100000;
}
else
{
//停止驱动
PORTC &= 0b11011111;
}
}
/***************************************************************************
系统初始化
****************************************************************************/
void Hardware_init(void)
{
CLI();
Port_init();
Timer1_init();
Timer0_init();
adc_init();
TIMSK = 0x04;
SEI();
}
/***************************************************************************
延时程序
****************************************************************************/
/*void Delay_ms(unsigned int delay_time)
{
Timer_Count_End=delay_time;
Timer_Count=1; //启动计数器
re_delay:
if (Timer_Count<=Timer_Count_End)
{
if (TCNT0>Mark_Line)
{
//驱动电机
PORTC |= 0b00100000;
}
else
{
//停止驱动
PORTC &= 0b11011111;
}
goto re_delay;
}
else
{
Timer_Count_End=0;
Timer_Count=0;
}
}*/
void Delay_ms(unsigned int m) //1ms延时
{
int l,j;
for(l=0;l<m;l++)
for(j=0;j<500;j++)
{
if (TCNT0>Mark_Line)
{
//驱动电机
PORTC |= 0b00100000;
}
else
{
//停止驱动
PORTC &= 0b11011111;
}
}
}
/***************************************************************************
按键扫描程序
****************************************************************************/
void Key_Press_Scan(void) //判断键值
{ //unsigned char temp=0;
//扫描第一列
Press_Keys=0;
PORTC = 0b00000111;
DDRC = 0b00110000;
//temp=PINC;
if ( (PINC&0b00000100) == 0)
{
Delay_ms(10);
if ((PINC&0b00000100) == 0)
{
Press_Keys=1;
}
}
else if ((PINC&0b00000010) ==0)
{
Delay_ms(10);
if ((PINC&0b00000010) ==0)
{
Press_Keys=2;
}
}
else if ((PINC&0b00000001) ==0)
{
Delay_ms(10);
if ((PINC&0b00000001) ==0)
{
Press_Keys=3;
}
}
/*
//扫描第二列
PORTC = 0b00010111;
DDRC = 0b00111000;
//temp=PINC;
if ( (PINC&0b00000100) == 0)
{
Delay_ms(10);
if ((PINC&0b00000100) == 0)
{
Press_Keys=4;
}
}
else if ((PINC&0b00000010) ==0)
{
Delay_ms(10);
if ((PINC&0b00000010) ==0)
{
Press_Keys=5;
}
}
else if ((PINC&0b00000001) ==0)
{
Delay_ms(10);
if ((PINC&0b00000001) ==0)
{
Press_Keys=6;
}
}*/
}
/***************************************************************************
显示函数
****************************************************************************/
void Display_Message(unsigned char Where,unsigned char Number,unsigned char delays)
{
//在指定的位置显示指定的数字
PORTD = DispBit[Where];
PORTB = DispCode[Number]; //调用数码管译码表
Delay_ms(delays);
}
/**************************************************************************
主函数
**************************************************************************/
void main(void)
{
Hardware_init();
ADCSRA |=(1<<ADSC); //启动AD转换
while(1)
{
if (TCNT0>Mark_Line)
{
//驱动电机
PORTC |= 0b00100000;
}
else
{
//停止驱动
PORTC &= 0b11011111;
}
Key_Press_Scan();
Display_Message(0,((Mark_Line<<4)>>4),5);
Display_Message(1,(Mark_Line>>4),5);
}
}
-----此内容被Gorgon Meducer于2005-01-22,18:48:05编辑过 |
|