时钟频率:内部RC 1M
芯片: ULN2003
键值:0 小角度快正转。1 小角度快倒。2 大角度快转。3 大角度快倒。
4 小角度正慢转。5 小角度倒慢转。6 大角度正慢转。7 大角度倒慢转。
********************************************************************/
#include<iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
uchar a=0,b=0
uchar KEY_num=0xe1
unsigned int m=9000
const uchar f1[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03}//正转时序 3.75度
const uchar f2[]={0x04,0x06,0x02,0x03,0x01,0x09,0x08,0x0c}//倒转时序 3.75度
const uchar f3[]={0x01,0x02,0x04,0x08}//正转时序 7.5度
const uchar f4[]={0x01,0x08,0x04,0x02}//倒转时序 7.5度
void delay(int k) //延时
{
int i
for(i=0i<ki++)
}
void delay_10ms(uint data)
{
uint m=2
while(data)
{
data--
m=2
while(m)m--
}
}
void zhengzhuan1(void) //正转3.75度
{
unsigned char j
for (j=0j<8j++)
{
PORTC=f1[j]
delay(m)
}
}
void daozhuan1(void) //倒转3.75度
{
unsigned char j
for (j=0j<8j++)
{
PORTC=f2[j]
delay(m)
}
}
void zhengzhuan2(void) //正转7.5度
{
unsigned char j
for (j=0j<4j++)
{
PORTC=f3[j]
delay(m)
}
}
void daozhuan2(void) //倒转7.5度
{
unsigned char j
for (j=0j<4j++)
{
PORTC=f4[j]
delay(m)
}
}
void port_int() //初始化端口
{
PORTB = 0xf0
DDRB = 0x0F
DDRC=0xff
PORTC=0x01
}
void init_devices(void)
{
CLI()//禁止所有中断
MCUCR = 0x00
MCUCSR = 0x80//禁止JTAG
GICR = 0x00
port_int()
SEI()//毕慧开全局中断
}
/派数带/按键键值读取程序
//返回按键键值,如果没有按键则返回0.
void KYY_read()
{
//定义按键尘芦值存放内存
PORTB=0xf0 //行全部送高电平
PORTB=0xf0
if((PINB&0xf0)!=0xf0) //有按键
{ delay_10ms(1)//延时消抖
if((PINB&0xf0)!=0xf0)//确定有按键按下
{ PORTB=0xfe //扫描第一行
PORTB=0xfe
if((PINB&0xf0)!=0xf0)
{
KEY_num=(PINB&0xf0)+1
a=9
}
PORTB=0xfd //扫描第二行
PORTB=0xfd
if((PINB&0xf0)!=0xf0)
{
KEY_num=(PINB&0xf0)+2
}
PORTB=0xfb //扫描第三行
PORTB=0xfb
if((PINB&0xf0)!=0xf0)
{
KEY_num=(PINB&0xf0)+4
}
PORTB=0xf7 //扫描第四行
PORTB=0xf7
if((PINB&0xf0)!=0xf0)
{
KEY_num=(PINB&0xf0)+8
}
}
}
//没有按键返回0
}
//按键执行程序
//送如参数:按键键值
KEY_do(uchar data)
{
uchar KEY_number=data
switch(KEY_number)
{
case 0xe1:a=0b=0daozhuan1()m=5000break
case 0xd1:a=0b=1daozhuan1()m=6000break
case 0xb1:a=0b=2daozhuan1()m=7000break
case 0x71:a=0b=3daozhuan1()m=8000break
case 0xe2:a=0b=4daozhuan2()m=5000break
case 0xd2:a=0b=5daozhuan2()m=6000break
case 0xb2:a=0b=6daozhuan2()m=7000break
case 0x72:a=0b=7daozhuan2()m=8000break
case 0xe4:a=0b=8zhengzhuan1()m=5000break
case 0xd4:a=0b=9zhengzhuan1()m=6000break
case 0xb4:a=1b=0zhengzhuan1()m=7000break
case 0x74:a=1b=1zhengzhuan1()m=8000break
case 0xe8:a=1b=2zhengzhuan2()m=5000break
case 0xd8:a=1b=3zhengzhuan2()m=6000break
case 0xb8:a=1b=4zhengzhuan2()m=7000break
case 0x78:a=1b=5zhengzhuan2()m=8000break
default:b=0break
}
}
void main (void)//主程序
{
init_devices()
while(1)
{
KYY_read()
KEY_do(KEY_num)
}
}
给你个参考程序,是MEGA16的,你可以自己看看。#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define DS1302_REST 6 //定义1302的RST接在PORTX.4
#define DS1302_IO 5 //定义1302的IO接在PORTX.3
#define DS1302_CLK4 //定义1302的时钟接在PORTX.2
#define DDRX DDRD
#define PORTX PORTD
#define PINX PIND
#define DS1302_REST_OUT DDRX|=1<<DS1302_REST //复位端置为输出
#define SET_DS1302_REST PORTX|=1<<漏或DS1302_REST//复位端置1
#define CLR_DS1302_REST PORTX&=~(1<<DS1302_REST) //复位端清0
#define DS1302_IO_OUT DDRX|=1<<DS1302_IO //数据端置为输出
#define DS1302_IO_IN DDRX&=~(1<<DS1302_IO)//数据端置1
#define SET_DS1302_IO PORTX|=1<<DS1302_IO //数据端清0
#define CLR_DS1302_IO PORTX&=~(1<<DS1302_IO) //数据端置为输入吵搜液
#define IN_DS1302_IO PINX&(1<<DS1302_IO) //数据端输入数据
#define DS1302_CLK_OUTDDRX|=1<<DS1302_CLK //时钟端置为输出
#define SET_DS1302_CLKPORTX|=1<<DS1302_CLK //时钟端置1
#define CLR_DS1302_CLKPORTX&=~(1<<DS1302_CLK) //时钟端清0
#define DS1302_Sec_Write 0x80 //秒数据写地址
#define DS1302_Sec_Read0x81 //秒数据读地址
#define DS1302_Min_Write 0X82 //升物分数据写地址
#define DS1302_Min_Read0X83 //分数据读地址
#define DS1302_Hour_Write 0X84 //时数据写地址
#define DS1302_Hour_Read 0X85 //时数据读地址
#define DS1302_Day_Write 0X86 //日数据写地址
#define DS1302_Day_Read0X87 //日数据读地址
#define DS1302_Month_Write 0X88 //月数据写地址
#define DS1302_Month_Read 0X89 //月数据读地址
#define DS1302_Week_Write 0X8A //星期数据写地址
#define DS1302_Week_Read 0X8B //星期数据读地址
#define DS1302_Year_Write 0X8C //年数据写地址
#define DS1302_Year_Read 0X8D //年数据读地址
#define DS1302_Control 0x8e //控制数据地址
#define DS1302_Charger 0x90 //充电控制地址
const Position[4]={0xFE,0XFD,0XFB,0XF7} //位选
const Led[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}//共阴数码管0~9
//const Led[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90} //共阳数码管0~9
uchar time[8]={0x00,0x08,0x10,0x18,0x06,0x09,0x55,0x00} //时钟初始写入数据
uchar second=5 //秒
uchar minute=0 //分
uchar hour=0 //时
uchar day=1 //日
uchar month=1//月
uchar year=6 //年
uchar week=7 //周
uchar disbuff[15]//显示缓冲
uchar TimeSign=0 //时钟显示标志,=0时,数码管显示秒分,=1时,显示分时
/*************************************
* DS1302 *** 作函数组 *
*************************************/
//写入1302数据函数:
//入口:addr为写入地址码,data为写入数据
//返回:无
void DS1302_Write(uchar addr,uchar data)
{
uchar i
DS1302_IO_OUT //配置IO为输出
CLR_DS1302_REST//清复位,停止所有 *** 作
CLR_DS1302_CLK //清时钟,准备 *** 作
SET_DS1302_REST//置复位,开始 *** 作
for(i=8i>0i--) //此循环写入地址码
{
if(addr&0x01)
SET_DS1302_IO //当前位为1,置数据位
else
CLR_DS1302_IO //当前位为0,清数据位
SET_DS1302_CLK //产生时钟脉冲,写入数据
CLR_DS1302_CLK
addr>>=1 //移位,准备写入下1位
}
for(i=8i>0i--) //此循环写入数据码
{
if(data&0x01)
SET_DS1302_IO
else
CLR_DS1302_IO
SET_DS1302_CLK
CLR_DS1302_CLK
data>>=1
}
CLR_DS1302_REST
DS1302_IO_IN //清输出状态
}
//从1302中读出数据:
//入口:addR为读数据所在地址
//返回:读出的数据data
char DS1302_Read(uchar addr)
{
uchar data,i
DS1302_IO_OUT //配置IO为输出
CLR_DS1302_REST//清复位,停止所有 *** 作
CLR_DS1302_CLK //清时钟,准备 *** 作
SET_DS1302_REST//置复位,开始 *** 作
for(i=8i>0i--) //此循环写入地址码
{
if(addr&0x01)
SET_DS1302_IO //当前位为1,置数据位
else
CLR_DS1302_IO //当前位为0,清数据位
SET_DS1302_CLK //产生时钟脉冲,写入数据
CLR_DS1302_CLK
addr>>=1 //移位,准备写入下1位
}
DS1302_IO_IN//端口输入
for(i=8i>0i--) //此循环读出1302的数据
{
data>>=1
if(IN_DS1302_IO)
data|=0x80
SET_DS1302_CLK
CLR_DS1302_CLK
}
CLR_DS1302_REST
return(data)
}
//检查1302状态
uchar Check_DS1302(void)
{
DS1302_Write(DS1302_Control,0x80)
if(DS1302_Read(DS1302_Control)==0x80) return 1
return 0
}
//向1302中写入时钟数据
void DS1302_Write_Time(void)
{
DS1302_Write(DS1302_Control,0x00)//关闭写保护
DS1302_Write(DS1302_Sec_Write,0x80) //暂停
//DS1302_Write(DS1302_Charger,0xA9)//涓流充电
DS1302_Write(DS1302_Year_Write,time[1]) //年
DS1302_Write(DS1302_Month_Write,time[2]) //月
DS1302_Write(DS1302_Day_Write,time[3]) //日
DS1302_Write(DS1302_Week_Write,time[4]) //周
DS1302_Write(DS1302_Hour_Write,time[5]) //时
DS1302_Write(DS1302_Min_Write,time[6]) //分
DS1302_Write(DS1302_Sec_Write,time[7]) //秒
DS1302_Write(DS1302_Control,0x80)//打开写保护
}
//从1302中读出当前时钟
void DS1302_Read_Time(void)
{
time[1]=DS1302_Read(DS1302_Year_Read) //年
time[2]=DS1302_Read(DS1302_Month_Read) //月
time[3]=DS1302_Read(DS1302_Day_Read) //日
time[4]=DS1302_Read(DS1302_Week_Read) //周
time[5]=DS1302_Read(DS1302_Hour_Read) //时
time[6]=DS1302_Read(DS1302_Min_Read) //分
time[7]=DS1302_Read(DS1302_Sec_Read) //秒
//BCD码到二进制的调整
second=((time[7]&0x70)>>4)*10+(time[7]&0x0f)
minute=((time[6]&0x70)>>4)*10+(time[6]&0x0f)
hour=((time[5]&0x30)>>4)*10+(time[5]&0x0f)
day=((time[3]&0x30)>>4)*10+(time[3]&0x0f)
month=((time[2]&0x10)>>4)*10+(time[2]&0x0f)
year=((time[1]&0x70)>>4)*10+(time[1]&0x0f)
}
void Time_Disbuffer() //显示缓冲
{
disbuff[0]=second%10
disbuff[1]=second/10
disbuff[2]=minute%10
disbuff[3]=minute/10
disbuff[4]=hour%10
disbuff[5]=hour/10
disbuff[6]=week
disbuff[7]=day%10
disbuff[8]=day/10
disbuff[9]=month%10
disbuff[10]=month/10
disbuff[11]=year%10
disbuff[12]=year/10
disbuff[13]=0
disbuff[14]=2
}
#pragma interrupt_handler time0:20 //T0比较匹配中断
void time0(void)
{
static uchar posit=0
static uchar sign=0
Time_Disbuffer()
switch(second%10) //控制秒点标志
{
case 0:sign=1break
case 1:sign=0break
case 2:sign=1break
case 3:sign=0break
case 4:sign=1break
case 5:sign=0break
case 6:sign=1break
case 7:sign=0break
case 8:sign=1break
case 9:sign=0break
}
if(TimeSign==0)//数码管显示分秒
{
PORTC=0XFF //消隐
PORTA=Led[disbuff[posit]] //数据
PORTC=Position[posit] //位选
}
if(TimeSign==1)//数码管显示时分
{
if((posit==2)&&sign) //控制秒点
{
PORTC=0XFF //消隐
PORTA=Led[disbuff[posit+2]]|0x80 //0x80的作用是使要显示的数字加上一个点
PORTC=Position[posit] //位选
}
else
{
PORTC=0XFF //消隐
PORTA=Led[disbuff[posit+2]] //数据
PORTC=Position[posit] //位选
}
}
if(++posit>3)posit=0
}
#pragma interrupt_handler INT_0:2//外部中断0
void INT_0(void)
{
switch(TimeSign)
{
case 0:TimeSign=1break
case 1:TimeSign=0break
}
}
void main()
{
DDRA=0XFF
DDRB=0XFF
DDRC=0XFF
DDRD=0XF0
PORTD=0x0F
TCCR0=0x0B
TCNT0=0x00
OCR0=0x50
TIMSK=0x02// 允许T/C0比较中断
GICR|=0X40
MCUCR=0X03
GIFR=0X80
DS1302_Write_Time()//写入初始时间
SREG=0X80 //总中断允许
while(1)
{
DS1302_Read_Time()
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)