|
这个是自己写的,按键无法互锁,就是按下键1运行时,可以按下键二停止
#include "iom16v.h"
#include "macros.h"
#include <AVR_PQ1A.h> //包含自定义常量头文件
#define uchar unsigned char
#define uint unsigned int
unsigned char F_Rotation[4]={0xF1,0xF2,0xF4,0xF8}; //正转表格,换算成二进制 0000 0001,0000 0010,0000 0100,0000 1000
unsigned char B_Rotation[4]={0xF8,0xF4,0xF2,0xF1}; //反转表格
unsigned char const Number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,};//0~9
unsigned char leddata[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82, 0xF8,0x80,0x90,0xFF};
uchar i;//定义变量
uint num;//定义计数变量
#pragma data:code//数组存放位置
flash table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
//顺时针转动
void MotorCW()
{
unsigned char i;
{
DDRB = 0xFF;
for(i=0;i<4;i++) //4相
{
PORTB=F_Rotation[i]; //输出对应的相 可以自行换成反转表格
delay(1); //改变这个参数可以调整电机转速 ,数字越小,转速越大
}
}
}
//逆时针转动
void MotorCCW()
{
unsigned char i;
{
DDRB = 0xFF;
for(i=0;i<4;i++) //4相
{
PORTB=B_Rotation[i]; //输出对应的相 可以自行换成反转表格
delay(1); //改变这个参数可以调整电机转速 ,数字越小,转速越大
}
}
}
void MotorStop()
{
DDRB = 0xFF;
}
unsigned char KeyResult;
//键盘按下判断函数
uchar key_press() //按键子函数 ,带返回值的子函数
{
uchar j; //定义变量J
DDRD|=0X0F; //按键低4位输出,其它不变
PORTD|=0X0F; //按键低4位输出高电平,其它不变
DDRD&=0XF0; //按键低4位输入,其它不变
j=PIND; //对变量J赋值
j=j&0X0F;//00001111 进行与运算,判断按键是否有按下
if(j==0X0F) //如果按键没有按下返回0,如按下返回1给 key_press
{
return 0;
}
else
{
return 1;
}
}
//*****************************扫描子函数**********************************
uchar key_scan()
{
uchar key; //定义变量KEY
delay(10); //延时10MS再次确定按键是否有被按下
if(key_press()) //判断按键 是否有被按下,则key_press为1,如按下则执行如下语句
{
key=PIND; //对变量KEY进行赋值
key&=0X0F; //进行运算判断一下是否真的有按下,如真的有按下,则有如下情况
switch(key) //条件语句
{
case 0X0E:key=0X0E;break; //a0按下所对应的数据 ,并执行KEY为1
case 0X0D:key=0X0D;break; //a1按下
case 0X0B:key=0X0B;break; //a2按下
case 0X07:key=0X07;break; //a3按下
default:key=0;break; //什么也没有按下
}
while(key_press()); //判断一下是否有松开
}
else //如果没有按下则执行如下语句
{
key=0; //变量赋值16
}
return key; //返回KEY给key_scan扫描函数
}
void light()
{ DDRA=0xff; //PA0~7为输出状态
PORTA=0x01; //PA0为输出低电平,而其余为高电平,亦即打亮LED0
}
void lightt()
{ DDRA=0xff; //PA0~7为输出状态
PORTA=0x02; //PA1为输出低电平,而其余为高电平,亦即打亮LED1
}
void lights()
{ DDRA=0xff; //PA0~7为输出状态
PORTA=0x04; //PA2为输出低电平,而其余为高电平,亦即打亮LED2
}
void lightf()
{ DDRA=0xff; //PA0~7为输出状态
PORTA=0x08; //PA3为输出低电平,而其余为高电平,亦即打亮LED3
}
void lightm()
{ DDRA=0xff; //灭灯
PORTA=0x00;
PORTA=0x80;
}
void light5()
{ DDRA=0xff;
PORTA=0x10;
}
void light6()
{ DDRA=0xff;
PORTA=0x20;
}
//电机程序
void turn()
{ uint j;
do
{
uint i;
delay(1);
light();//******************第一台电机转动指示灯
for (i=0;i<100;i++)
{ MotorCW();//顺时针转动
}
delay(10);
MotorStop(); //停止转动
delay(10);
for (i=0;i<100;i++)
{ MotorCCW();//逆时针转动
}
delay(10);
MotorStop();//停止转动
delay(1);
lightt();//****************第二台
for (i=0;i<100;i++)
{ MotorCW();//顺时针转动
}
delay(10);
MotorStop(); //停止转动
delay(10);
for (i=0;i<100;i++)
{ MotorCCW();//逆时针转动
}
delay(10);
MotorStop();//停止转动
delay(1);
lights();//*******************第三台
for (i=0;i<100;i++)
{ MotorCW();//顺时针转动
}
delay(10);
MotorStop(); //停止转动
delay(10);
for (i=0;i<100;i++)
{ MotorCCW();//逆时针转动
}
delay(10);
MotorStop();//停止转动
delay(1);
lightf();//*****************第四台
for (i=0;i<100;i++)
{ MotorCW();//顺时针转动
}
delay(10);
MotorStop(); //停止转动
delay(10);
for (i=0;i<100;i++)
{ MotorCCW();//逆时针转动
}
delay(10);
MotorStop();//停止转动
delay(1);
lightm();
delay(10);
xianshi();
}while(j!=0X0E);
}
//数码管显示
void xianshi()
{
uint i;
for(i=0;i<20;i++)//显示20次,使整体看起来不闪烁
{
PORTC=table[num%10];
delay(10);}
if(PORTA=0x80)
num++;
}
main(void)
{
uint j,m;
while(1)
{
j=key_scan();
switch(j)
{
case 0X0E:turn();
xianshi();break;
case 0X0D:num=0;light5();break;
case 0X0B:MotorStop();light6();break;
}
delay(10);
}
}
这个是按您的书上的状态机按键,但是按键没反应,不知道什么原因
#include "iom16v.h"
#include "macros.h"
#include <AVR_PQ1A.h> //包含自定义常量头文件
#define uchar unsigned char
#define uint unsigned int
unsigned char F_Rotation[4]={0xF1,0xF2,0xF4,0xF8}; //正转表格,换算成二进制 0000 0001,0000 0010,0000 0100,0000 1000
unsigned char B_Rotation[4]={0xF8,0xF4,0xF2,0xF1}; //反转表格
unsigned char const Number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,};//0~9
unsigned char leddata[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82, 0xF8,0x80,0x90,0xFF};
uchar i;//定义变量
uint num;//定义计数变量
flash table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
//顺时针转动
void MotorCW()
{
unsigned char i;
{
DDRB = 0xFF;
for(i=0;i<4;i++) //4相
{
PORTB=F_Rotation[i]; //输出对应的相 可以自行换成反转表格
delay(1); //改变这个参数可以调整电机转速 ,数字越小,转速越大
}
}
}
//逆时针转动
void MotorCCW()
{
unsigned char i;
{
DDRB = 0xFF;
for(i=0;i<4;i++) //4相
{
PORTB=B_Rotation[i]; //输出对应的相 可以自行换成反转表格
delay(1); //改变这个参数可以调整电机转速 ,数字越小,转速越大
}
}
}
void MotorStop()
{
DDRB = 0xFF;
}
#define key_input PIND // 按键输入口
#define key_no 0b11111111
#define key_k1 0b00001110
#define key_k2 0b00001101
#define key_k3 0b00001011
#define key_k4 0b00000111
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
unsigned char read_key(void) //按键扫描程序
{
static unsigned char key_state = 0,key_old;
unsigned char key_press,key_return = key_no;
key_press = key_input; // 读按键I/O电平
switch (key_state)
{
case key_state_0: // 按键初始态
if (key_press != key_no)key_state = key_state_1;
break; // 键被按下,状态转换到键确认态
case key_state_1: // 按键确认态
if (key_press == key_old) // 与原电平比较(消抖处理)
{
key_return = key_press;
key_state = key_state_2; // 状态转换到判键释放态
}
else
key_state = key_state_0; // 按键已抬起,转换到按键初始态(消抖)
break;
case key_state_2:
if (key_press != key_old)
key_state = key_state_0; //按键已释放(或转按其它键),转换到按键初始态
break;
}
key_old = key_press;
return key_return;
}
void light()
{ DDRA=0xff; //PA0~7为输出状态
PORTA=0x01; //PA0为输出低电平,而其余为高电平,亦即打亮LED0
}
void lightt()
{ DDRA=0xff; //PA0~7为输出状态
PORTA=0x02; //PA1为输出低电平,而其余为高电平,亦即打亮LED1
}
void lights()
{ DDRA=0xff; //PA0~7为输出状态
PORTA=0x04; //PA2为输出低电平,而其余为高电平,亦即打亮LED2
}
void lightf()
{ DDRA=0xff; //PA0~7为输出状态
PORTA=0x08; //PA3为输出低电平,而其余为高电平,亦即打亮LED3
}
void lightm()
{ DDRA=0xff; //灭灯
PORTA=0x00;
PORTA=0x80;
}
void light5()
{ DDRA=0xff;
PORTA=0x10;
}
void light6()
{ DDRA=0xff;
PORTA=0x20;
}
//电机程序
void turn()
{
while(1)
{
uint i;
delay(1);
light();//******************第一台电机转动指示灯
for (i=0;i<100;i++)
{ MotorCW();//顺时针转动
}
delay(10);
MotorStop(); //停止转动
delay(10);
for (i=0;i<100;i++)
{ MotorCCW();//逆时针转动
}
delay(10);
MotorStop();//停止转动
delay(1);
lightt();//****************第二台
for (i=0;i<100;i++)
{ MotorCW();//顺时针转动
}
delay(10);
MotorStop(); //停止转动
delay(10);
for (i=0;i<100;i++)
{ MotorCCW();//逆时针转动
}
delay(10);
MotorStop();//停止转动
delay(1);
lights();//*******************第三台
for (i=0;i<100;i++)
{ MotorCW();//顺时针转动
}
delay(10);
MotorStop(); //停止转动
delay(10);
for (i=0;i<100;i++)
{ MotorCCW();//逆时针转动
}
delay(10);
MotorStop();//停止转动
delay(1);
lightf();//*****************第四台
for (i=0;i<100;i++)
{ MotorCW();//顺时针转动
}
delay(10);
MotorStop(); //停止转动
delay(10);
for (i=0;i<100;i++)
{ MotorCCW();//逆时针转动
}
delay(10);
MotorStop();//停止转动
delay(1);
lightm();
delay(10);
xianshi();
}}
//数码管显示
void xianshi()
{
uint i;
for(i=0;i<20;i++)//显示20次,使整体看起来不闪烁
{
PORTC=table[num%10];
delay(10);}
if(PORTA=0x80)
num++;
}
void main()
{
unsigned char key_temp;
while(1)
{
key_temp= read_key();
switch(key_temp )
{
case key_k1:
turn();xianshi();
break;
case key_k2:MotorStop();light5();break;
}
delay(10);
}
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。
|