求AVR-ATmega32单片机及ULN2003A达林顿管驱动的步进电机的C 程序

求AVR-ATmega32单片机及ULN2003A达林顿管驱动的步进电机的C 程序,第1张

很巧合,我做的开发板上面正好有这个程序,是mega16的,16和32管脚兼容,只不过flash大小不一样,不过中断向量号也不一样,你看下自己改改。

时钟频率:内部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()

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12364749.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存