首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

单片机的中duan解决方法

2012-06-03 
单片机的中duan#includereg52.h#define uchar unsigned char#define uint unsigned int#define KeyPortP

单片机的中duan
#include<reg52.h>

#define uchar unsigned char
#define uint unsigned int
#define KeyPort P0

sbit RS=P2^0;
sbit RW=P2^1;
sbit En=P2^2;

sbit Pwm=P2^3;
sbit Out1=P2^4;
sbit Out2=P2^5;
sbit Wave=P2^6;

uchar code table[]={'0','1','2','3','4','5','6','7','8','9'};//转换成液晶显示的字符
uint wave_num=0,n;
uint change=0;
uint time=0;
uint high=20;
uint cycle=40;
uint key[4];
uint NUM,NUM_H,NUM_L;
static uint i;



//延迟Zms
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}


//向LCD写入命令
void write_com(uchar com)
{
RS=0;
RW=0;
P1=com;
delay(5);
En=1;
delay(5);
En=0;
}

//向LCD写入字符
void write_data(uchar date)
{
RS=1;
  RW=0;
P1=date;
delay(5);
En=1;
delay(5);
En=0;
}

//在LCD的特定位置显示字符
void write_char(uchar x,uchar y,uchar date)
{
if(y==0)
write_com(0x80+x);
else
write_com(0xc0+x);
  write_data(date);
}

//在LCD特定的位置显示字符串
void write_string(uchar x,uchar y,uchar *s)
{
if(y==0)
write_com(0x80+x);
else
write_com(0xc0+x);
  while(*s)
{
write_data(*s);
s++;
}
}

//LCD清屏
void LCD_Clear()
{
write_com(0x01);
delay(5);
}

//LCD初始化
void Init_LCD()
{
En=0;
write_com(0x38);//设置显示模式(两行显示)
write_com(0x0e);//显示光标并闪烁
write_com(0x06);//光标左移加1
write_com(0x01); //清屏
write_com(0x80);//整屏移动,起始位地址设为第一行的?
}//最后一位




uchar KeyScan(void) //键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l; //行列值中间变量
KeyPort=0x0f; //行线输出全为0
cord_h=KeyPort&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(10); //去抖
if((KeyPort&0x0f)!=0x0f)
{
cord_h=KeyPort&0x0f; //读入列线值
KeyPort=cord_h|0xf0; //输出当前列线值
cord_l=KeyPort&0xf0; //读入行线值

while((KeyPort&0xf0)!=0xf0); //等待松开并输出

return(cord_h+cord_l); //键盘最后组合码值
}
}
return(0xff); //返回该值
}




void Wave_test()//计脉冲个数
{
  while(1)
  {
while(!Wave);//检测到高电平
if(Wave)
  {
wave_num++;//高电平计数
while(Wave);//高电平等待
}
  }
}

uint speed_count()
{
return(wave_num/4); //假设转轴上有4个磁钢

}



/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------*/
uchar Key_In(void)
{
 switch(KeyScan())
 {
  case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
  case 0x7d:return 1;break;//1
  case 0x7b:return 2;break;//2
  case 0x77:return 3;break;//3
  case 0xbe:return 4;break;//4
  case 0xbd:return 5;break;//5
  case 0xbb:return 6;break;//6
  case 0xde:return 8;break;//8
  case 0xb7:return 7;break;//7
  case 0xdd:return 9;break;//9
  case 0xdb:return 10;break;//a
  case 0xd7:return 11;break;//b
  case 0xee:return 12;break;//c
  case 0xed:return 13;break;//d
  case 0xeb:return 14;break;//e
  case 0xe7:return 15;break;//f
  default:return 0xff;break;
 }
}

//定时器T0.T1的初始化
void Init_timer()
{

IE0=1;
  TMOD=0x11;
   
  TH0=0xec;
  TL0=0x78;
TR0=1;
   

TH1=0x3c;


TL1=0xb0;
  TR1=1;

}


void Timer0() interrupt 3 using 2
{
  time++;
  TH0=0xec; //每次定时5ms,周期为200ms
  TL0=0x78;
   
  if(change==0)
  {  
  Pwm=1;
Out1=1;//
Out2=0;
  if(time==high)
  Pwm=0;
  else if(time==cycle)
  {
  Pwm=1;
  time=0;
}
}
  else
  {  
  Pwm=1;
Out2=1;
Out1=0;
  if(time==high)
  Pwm=0;
  else if(time==cycle)
  {
  Pwm=1;
  time=0;
}
}
}

void Timer1() interrupt 1 using 0
{
static uchar sec_cnt=20;
  uint N;
TR1=0;
  TH1=0x3c; //每次定时50ms
  TL1=0xb0;
  sec_cnt--;
  if(!sec_cnt) //1s到,计算转速并比较及显示
{
  N=speed_count();
  if(N>NUM_H)
  do
  {
  high--;
sec_cnt=20;
wave_num=0;
TR1=1;
}while(N<=NUM_H); 
else if(N<NUM_L)
  do
{
  high--;
  sec_cnt=20;
wave_num=0;
  TR1=1;
}while(N>=NUM_L);
}
  write_char(11,1,table[N/1000]);
  write_char(12,1,table[N%1000/100]);
  write_char(13,1,table[N%1000%100/10]);
  write_char(14,1,table[N%10]);
TR1=1;
}


void main()
{
uchar num;
Init_LCD();

  write_com(0x01);
delay(5);
  write_com(0x0f);
delay(5);
  write_string(0,0,"Set Speed:");
  delay(5);
write_string(0,1,"Test Speed:");
  delay(5);
 Init_timer();
  Pwm=0;
  while(1)
{
num=Key_In();
  if(num!=0xff)//显示按键数
{
if(num>=0&&num<=9)
do
{
write_char(10+i,0,table[num]);
delay(5);
key[i]=num;
i++;
  break;
//if(i==4)
  //i=0;
}while(i==4);
   

  if(num==10) //开启电机
{
EA=1;
/*switch(--i)
  {
case 0:NUM=key[0];break;
case 1:NUM=key[0]*10+key[1];break;
case 2:NUM=key[0]*100+key[1]*10+key[2];break;
case 3:NUM=key[0]*1000+key[1]*100+key[2]*10+key[3];break;
}
  NUM_H=NUM*1.01;
  NUM_L=NUM*0.99;
  high=NUM*40/400; 
  //write_data(table[high%10]);*/
}

  if(num==11) //关掉电机
EA=0;
if(num==12)//开始测量
  {
ET1=1;
Wave_test();
  }
if(num==13)//控制电机正反转
change=~change;  
  if(num==14)//清屏
LCD_Clear();
  }

  }
}

  此程序旨在利用单片机控制直流电机转速,定时器T0旨在产生Pwm波,定时器T1旨在利用霍尔元件产生的脉冲进行计数,可测试的时候,不能产生Pwm波,望高手指点迷津,拜托了!

[解决办法]
1.在T0里面运行LED或者蜂鸣器之类,确认T0是否正确运行
2.在主函数里运行IO控制,确认IO控制是否正常
3.确认T0定时,是设计需要的宽度,正确使用示波器测试
···
[解决办法]


程序是慢慢调的 一个功能一个功能来
不确定的地方多用各种仪器 或者用打印信息来看
[解决办法]
我看楼主连PWM概念都没有搞清楚.建议去www.2010led.net这个网站,搜索一下PWM学习一下.
[解决办法]
太长了 楼主一点不调试就把代码贴上来 看代码比便代码累啊
[解决办法]
楼主能否注意一下编码的格式,这样没法看啊!

热点排行