请单片机高手看一下程序哪里出错

作者&投稿:岳荔 (若有异议请与网页底部的电邮联系)
单片机高手看一下下面这个程序!~

你的程序有点小错误!
CJNE R1,#6,MAIN
INC R1
AJMP LOOP
这个地方出了毛病,因为CJNE为不相等转移指令,所以呢,程序运行到它的时候都会转到MAIN ,然后R1又重新负值:0
所以程序不会运行到INC R1指令,也不会运行,AJMP LOOP 指令,所以,你实验的时候总是循环把数值7FH给P1口输出! 也就是说只有第一只灯亮!
本人认为这部分应该改为:
CJNE R1,#6,LOOP
INC R1
AJMP MAIN
试试看吧!!!!!

程序没有错误,可以正常执行。

这个程序把 4574 加上 6728,得出 01 13 02,分别存到1F 20 21H单元了。
用单步调试,可以看到每一步的作用,程序完全是正常工作的。

LCALL、ACALL,都可以统一写成 CALL,
没有必要写成 LCALL、ACALL,这些写法,编译软件会自动完成。

#include <AT89X52.H>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

//ADC0832端口
sbit ADCS = P1^1;
sbit ADCLK = P1^2;
sbit ADDI = P1^3;
sbit ADDO = P1^3;

//液晶屏端口
sbit RST = P2^0; //复位端
sbit E = P2^1; //使能端
sbit RW = P2^2; //使能端
sbit RS = P2^3; //模式端
sbit CS1 = P2^4;
sbit CS2 = P2^5;

sbit K4=P1^0;
sbit K5=P1^1;
sbit K6=P1^2;
sbit K7=P1^3;

//时钟芯片端口
sbit RST2 = P3^5; // 复位线引脚
sbit CLK = P3^6; // 时钟线引脚

#define Disp_On 0x3f //显示开指令
#define Disp_Off 0x3e //显示关指令
#define Col_Add 0x40 //定位到第0列指令
#define Page_Add 0xb8 //定位到第0页指令
#define Start_Line 0xc0 //定位从DDROM中的第0行开始往屏幕上显示

/*---------------定义时间日期显示缓存 ----------------------*/
uchar Curtime[7];
uchar day,sec,min,hour,date,month,year,hms,n,fla_cou;
uchar code shuzi[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
uchar xdata dsw[20]; //存放sprintf转换字符
uchar xdata value[149]; //点阵字符储存
void select_item(unsigned char);
idata unsigned char user_choosen=0;
idata unsigned char max_item=0;
idata unsigned char temp_choosen;
idata unsigned char shuaxin=0;
idata struct menu_item main1_menu[4]; //每个菜单项为一个元素.整个菜单地址即为数组名.
data struct menu_item measure_menu[2];
idata struct menu_item store_menu[2];
uchar menu_led,keyval,nusekey;

/**********初始化CPU************/
void init_cpu()
{
EA=1;
TR0=1;
TR1=1;
TMOD=0x11;
TH1=0x3c;
TL1=0xb0;
}

/*-------------------------时钟初始化子函数----------------------------*/
void Init_Clock(void)
{
//K1=1;
//K2=1;
//K3=1;
K4=1;
K5=1;
K6=1;
K7=1;
//KT=0;
//n=0;
TMOD=0x01; //定时器T0工作模式1
TH0=0x3c; //50ms
}

void delay(unsigned int t) //延时
{
unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<10;j++);
}

/*-------------------------写命令到LCD------------------------------*/
void write_command(unsigned char cmdcode)
{
RS = 0;
RW = 0;
P0 = cmdcode;
delay(0);
E = 1;
delay(0);
E = 0;
}

/*-----指定位置显示汉字16*16-----------------------*/
void hz_disp16(unsigned char pag,unsigned char col, unsigned char mod,unsigned char code *hzk)
{
uchar i;
pag=0;
col=0;
mod=0;
i=*hzk;
}

/*------------------初始化LCD屏--------------------------*/
void init_lcd()
{
RST=0;
delay(100);
RST=1;
delay(100);

CS2=1;
CS1=1;
delay(100);
write_command(Disp_Off);
write_command(Page_Add+0);
write_command(Start_Line+0);
write_command(Col_Add+0);
write_command(Disp_On);
}

/*-------------------------写数据到LCD----------------------------*/
void write_data(unsigned char Dispdata)
{
Dispdata=0;
}

/*------------------------清显示屏--------------------------------*/
void Clr_Scr()
{
unsigned char j ,k;

//清左半屏
CS2=1;CS1=0;
write_command(Page_Add+0);
write_command(Col_Add+0);
for(k=0;k<4;k++) //清左上半屏
{
// write_command(Page_Add+k);
for(j=0;j<64;j++)
write_data(0x00);
}

for(k=0;k<4;k++) //清左下半屏
{
write_command(Page_Add+4);
for(j=0;j<64;j++)
write_data(0x00);
}

//清右半屏
CS2=0;CS1=1;
write_command(Page_Add+0);
write_command(Col_Add+0);
for(k=0;k<4;k++) //清右上半屏
{
for(j=0;j<64;j++)
write_data(0x00);
}
for(k=0;k<4;k++) //清右下半屏
{
write_command(Page_Add+4);
for(j=0;j<64;j++)
write_data(0x00);
}
}

/*------------------显示12864图片------------------------------*/
void Disp_Img(unsigned char code *img)
{
uchar i;
i=*img;
}

void GetTime()
{}

/*-------------------------- 刷新显示子函数--------------------------*/
void Refresh(void)
{
GetTime();
CS1=1;CS2=0;

if(K6)
{
//sz_disp16(5,40,1,shuzi[sec%10]); //秒位
//sz_disp16(5,32,1,shuzi[sec/10]); //十秒位
}
else
{
hz_disp16(5,32,1,"kongbai2"); //秒位 十秒位
}

if(K5)
{
//sz_disp16(5,8,1,shuzi[min&0x0f]); //分钟位
//sz_disp16(5,0,1,shuzi[min>>4]); //十分位
}
else
{
hz_disp16(5,0,1,"kongbai2");
}
}

//附录三 ADC0832程序
uint Adc0832(unsigned char channel) //AD转换,返回结果
{
uchar i=0,j,ndat=0;
uint dat=0;

if(channel==0)channel=2;
if(channel==1)channel=3;

ADDI=1;
_nop_();
_nop_();
ADCS=0; //拉低CS端
_nop_();
_nop_();
ADCLK=1; //拉高CLK端
_nop_();
_nop_();
ADCLK=0; //拉低CLK端,形成下降沿1
_nop_();
_nop_();
ADCLK=1; //拉高CLK端
ADDI=channel&0x1;
_nop_();
_nop_();
ADCLK=0; //拉低CLK端,形成下降沿2
_nop_();
_nop_();
ADCLK=1; //拉高CLK端
ADDI=(channel>>1)&0x1;
_nop_();
_nop_();
ADCLK=0; //拉低CLK端,形成下降沿3
ADDI=1; //控制命令结束
_nop_();
_nop_();
dat=0;

for(i=0;i<8;i++)
{
dat|=ADDO; //收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0; //形成一次时钟脉冲
_nop_();
_nop_();
dat<<=1;
if(i==7)dat|=ADDO;
}

for(i=0;i<8;i++)
{
j=0;
j=j|ADDO; //收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0; //形成一次时钟脉冲
_nop_();
_nop_();
j=j<<7;
ndat=ndat|j;
if(i<7)ndat>>=1;
}

ADCS=1; //拉低CS端
ADCLK=0; //拉低CLK端
ADDO=1; //拉高数据端,回到初始状态
dat<<=8;
dat|=ndat;
return(dat); //return ad k
}

/*------------------------时钟固定汉字显示-----------------------*/
void ClockMsg(void)
{
Clr_Scr(); // 先清屏
CS2=1;CS1=0; // 左屏
hz_disp16(1,32,1,"xing"); //星-期-2-0-年-时
CS2=0;CS1=1; //右屏
hz_disp16(3,0,1,"yue"); //月-日-分-秒
}

void main_Menu()
{
uchar k,ltemp;
float l;
Clr_Scr(); //先清屏
CS2=1;
CS1=0;
hz_disp16(0,32,1,"jiaquan"); //甲//醛//测//量//数//据//存//储
delay(2000);
do
{
k=Adc0832(0); //AD转换结果
l=k/255.0*100.0;
ltemp=floor(l);
dsw[0]=ltemp/10;
dsw[1]=ltemp%10;
//sprintf(dsw,"%2.3f",l);
//dsw[0]=1;
switch(dsw[0])
{
case 0:
hz_disp16(2,32,1,"sz0");
break;
case 1:
hz_disp16(2,32,1,"sz9");
}
switch(dsw[1])
{
case 0:
hz_disp16(2,40,1,"sz0");
break;
case 1:
hz_disp16(2,40,1,"sz9");
}
//sz_disp16(2,40,1,sz0);
//*tra(dsw);
CS2=1;CS1=0;
//sz_disp16(2,56,1,value[10]);
}
while(P1_3);
}

void led_menu_show()
{
uchar n;
//max_item=menu_led->menu_count;

if (max_item>=4) //菜单项为3则表示为主菜单.
{
for(n=0;n<4;n++)
{
//draw_bmp(n*2,20,96,0,menu_led[n].display);
}
select_item(user_choosen); //标记出当前菜单项.
}

else
{
switch(temp_choosen)
{ case 0:
//draw_bmp(0,20,96,0,measurearray); //"开始测量"数组//
break;
default:
break;
}

for(n=0;n<max_item;n++)
{
//draw_bmp((n+1)*2,20,32,0,menu_led[n].display);
}
select_item(user_choosen+1);
}
}

void main_menu_initial() //LCD主菜单初始化.//
{
//main1_menu[0].menu_count=4; //有4个菜单项.//

//main1_menu[0].display=measurearray; //定义一个"开始测量"数组//
//main1_menu[0].subs=NULL;
//main1_menu[0].children_menus=measure_menu; //当前菜单子菜单的指针
//main1_menu[0].parent_menus=NULL; //还有"数据存储"、"时间设置"……//
}

void measure_menu_initial() //"开始测量"菜单设置//
{
//measure_menu[0].menu_count=2;
//measure_menu[0].display=qr; //开始测量函数, 确认.
//measure_menu[0].subs=start_measure_function; //开始测量函数
//measure_menu[0].children_menus=NULL;
//measure_menu[0].parent_menus=main1_menu;

//measure_menu[1].menu_count=2;
//measure_menu[1].display=qx; //开始测量函数, 取消.
//measure_menu[1].subs=NULL;
//measure_menu[1].children_menus=NULL;
//measure_menu[1].parent_menus=main1_menu;
}

void store_menu_initial(){}
void time_menu_initial(){}
void led_menu_pro()
{
//max_item=menu_led->menu_count;
switch(keyval)
{
case 0: break;
case 1: //向上键.
if(user_choosen==0)
{
user_choosen=max_item;
}
shuaxin=1;
user_choosen--;
break;
}
//"向上""向下""确认""取消"键//
if(shuaxin) //是否需要刷新LCD标志位.
{
Clr_Scr();
shuaxin=0;
}

led_menu_show();
}

//附录四 按键程序
#define nullkey 0 //定义//
uchar get_key() //读键//
{
uchar pass,kcodebuf;
static uchar lastkcode,keytime=0; //定义为静态变量,外部不可见,但需要常驻内存.
static uchar havekey=0;
static uchar keylock=0;

kcodebuf=P1 & 0xff;
keytime++;

if (kcodebuf!=lastkcode)
{
keytime=0;
}

if (kcodebuf==0xff)
{
havekey=0;
keylock=0;
keytime=0;
pass=0;
}

else
pass=nusekey;
lastkcode=kcodebuf;
return(pass);
}

/*----------------主函数-------------------*/
main()
{
init_cpu();
Init_Clock();
init_lcd();
Disp_Img(0x11);
delay(2000);
ClockMsg();
Refresh();
delay(2500);
Clr_Scr();
main_Menu();
Clr_Scr();
main_menu_initial();
measure_menu_initial();
store_menu_initial();
time_menu_initial();
//communication_menu_initial();
while(1)
{
keyval=get_key();
led_menu_pro();
}
}

是程序问题吗 故障现象是什么


各位单片机高手,哪位帮我分析一下下面这个程序,问题出...
回答:首先给你解释一下“<<”位移符的作用: 因为你的P1=0xfe,二进制数据就是11111110,左移一位之后为11111100,0往左移了一位,但是最低位系统自动以0补齐,而0x7f的二进制数据位01111111,所以if语句是永远进入不了的。 当然,针对此问题,C51给出了一个解决方案: 使用_crol_()函数可解决此问题...

单片机高手帮我看一下程序 用数码管的前两位显示一个十进制数,变化范围...
include<reg52.h> define uchar unsigned char define uint unsigned int sbit key1=P3^4;sbit key2=P3^5;sbit key3=P3^6;sbit key4=P3^7;sbit dula=P2^6;sbit wela=P2^7;uchar code table[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x5b,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0...

请单片机高手看一下程序哪里出错
idata unsigned char shuaxin=0; idata struct menu_item main1_menu[4]; \/\/每个菜单项为一个元素.整个菜单地址即为数组名.data struct menu_item measure_menu[2];idata struct menu_item store_menu[2];uchar menu_led,keyval,nusekey;\/***初始化CPU***\/void init_cpu(){ EA=1; TR0=1; TR1=1...

请高手帮忙看下针对stc单片机的这句程序是什么意思?
RegXXX = XXX_ENABLE | XXX_DOUBLE;这样的主要优点是清晰明了,即使对于这款单片机不熟悉的人也能一眼就看懂这行语句的目的。例如我虽然从未接触过STC单片机,但是我能知道你的那句程序大致是要为ADC模块开启供电、配置速度并打开指定的某个通道。以上。

那位单片机高手帮我看一下汇编程序
没有死循环的,你看到读数值会变,就没错了,单步很慢的。计数要到溢出时,TF0才由硬件置1 ,程序转到LP1执行。你可设置TH0TL0大一点的数,接近0FFFFH,就好看出了。参考资料:i 没有死循环

求高手帮忙看一下一些单片机代码
1,数组LED[]的第一个元素是LED[0],应该从LED[0]到LED[7];2,for循环里对n的值没有限定条件 include <reg52.h> define uint unsigned int sbit D1=P1^0;sbit D2=P1^1;sbit D3=P1^2;sbit D4=P1^3;sbit D5=P1^4;sbit D6=P1^5;sbit D7=P1^6;sbit D8=P1^7;uint n;uint...

求单片机高手帮忙详细解释下程序 特别是中断那
这是定时器到时产生中断后的处理过程。先看C100us+1(即低位字段)是否为0,不为0即jnz(jump not zero)就跳转至Goon处,否则就将C100us(即高位字段)减一,然后执行Goon。Goon:dec C100us+1 mov a, C100us orl a, C100us+1 jnz Exit ; 100us 记数器不为0, 返回 mov ...

求汇编语言单片机高手看看这个程序,补全一下
DEC B 是B寄存器内容自减1,INC B是B寄存器内容自加1。执行完main 以后直接执行LOOP,然后一直循环LOOP子程序,当然在键盘按下产生中断时,跳到ORG 0003H或者ORG 0013H段落执行,执行到RETI语句后再返回到LOOP段落循环,(1)处003H;(2)处RETI;(3)处#TAB;(4)处MOV;(3)处LOOP。

51单片机高手帮我看下这程序那错了 为何烧进去只有一个灯亮
问题在P2=~(1<<j++)上,由于++运算优先级高于<<故而这里没错,但是,P2实际的值为1左移j位,实际上仍是8位里面只有一个1,去繁殖后就是一个0.所以才会是只有一个灯亮

单片机高手,请帮个忙,看下这段程序的原理是什么
可以仿照十进制的除法来理解。只不过商的每一位只是0或1,也就是说先用高位的被除数减去除数,结果只有两种:1,高位大于被除数(商1);2,高位小于被除数(商0).没有十进制那麽多的情况,所以每往左移一位都可以直接用减法。而上面的算法只不过是通过移位把商放在R5的后面了,左移八次后正好商...

重庆市17730377130: 我 编了个单片机程序不知道哪出错了请高手指点一下?
江琬四磨: djnz r2,#$改为djnz r2,$

重庆市17730377130: 刚接触单片机 编的程序有一个错误找半天找不出来啊 高手帮忙看看下面程序是哪儿错了 啊 急急急~ 感激不尽 -
江琬四磨: 第三行的警告是因为没有声明init()函数,需要在main函数之前声明一下.第六行的错误是因为“flag_10ms”在使用前没有声明,需要在使用之前声明.同样下面的“flag_10ms”也是这个原因.另外我看“flag_20ms”也没有声明

重庆市17730377130: 帮忙看一下这个单片机程序错在哪里?总是编译错误.(答案正确的话会加分) -
江琬四磨: 经本人的复制编译下肯定确认本程序本身没有错误,根据自费一个错误提示 *** ERROR L104: MULTIPLE PUBLIC DEFINITIONSSYMBOL: MAIN 有MAIN的符号的函数被重复定义 有可能这个项目下还有还有其它文件有MAIN这个主程序,要么是编译器本身的问题

重庆市17730377130: 单片机 在写程序的时候出现了这样的错误 想问一下是哪里出现了错误 -
江琬四磨: WARNING L15: MULTIPLE CALL TO SEGMENT 在第十五行时有多个调用

重庆市17730377130: 求大神帮我查看我哪里出错了、单片机编程问题 -
江琬四磨: 第一,不要相信仿真,很多程序,实物已经工作的,仿真没办法正常.第二,从图中的效果,可以推断,应该是数码管选型错误.代码表与电路都是 共阳数码管,图中的数码管很可能是 共阴数码管.第三,程序太次了,累赘过多.光是 拨码开关的读取,就应该直接p=P1,还搞什么 L0~L7,a~h.8个拨码开关,典型的 uchar 数值,用不上 uint 值.

重庆市17730377130: C语言单片机程序 初学大家帮忙看看错在哪里了 #include <reg51.h> void main() { while(1) { P1=0x55; } } -
江琬四磨: C语言单片机程序 初学大家帮忙看看错在哪里了 #include void main() { while(1) { P1=0x55; } }程序百分百没问题,可能是编译的有问题,你 用的是keil编译的吗? 建议你多重新编译一下, 也有可能是...

重庆市17730377130: 刚刚用C语言写的单片机程序,帮忙看看哪里错了. -
江琬四磨: 主程序改一下:void main() { init(); while(1); }

重庆市17730377130: 简单 单片机程序 没报错, 帮忙看看错误在哪 -
江琬四磨: #include<reg52.h> //用T0计时 中断方式让P0闪烁#define uchar unsigned char void main() {P0 = 0x00; //先让灯亮着,以便发现硬件问题 EA=1; ET0=1; TR0=1; TMOD=0X02; TH0=100; TL0=100;while(1)//循环内部不要重复设置中断 更不要清零...

重庆市17730377130: 单片机问题,看看程序哪里出问题?O(∩ - ∩)O谢谢,看了半天没看出来 -
江琬四磨: 1. 51应该是低电平有效的,所以如果直接驱动LED时,0表示亮,1表示灭2. sbit是定义位的,而你定义了整个端口3. 没有加延时,闪烁过程很快,你应该看不到闪烁 所以:更改如下:#include<reg51.h>#define uint16 unsigned int //把unsignde ...

重庆市17730377130: 单片机工程师来看一下我为什么总是出错呢
江琬四磨: 下图加红圈就是你汇编程序漏写的. 第一处红框最好写上,虽然编译不会出错; 第二处红框是一个错误,LJMP长转移指令后没操作数,你这应该是控制P1口的8个LED灯亮灭的程序,所以是一个循环,LJMP后加MAIN,转移到MAIN处循环.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网