标题:
51单片机简易计算器程序报错
[打印本页]
作者:
zy020409
时间:
2017-12-22 23:15
标题:
51单片机简易计算器程序报错
课设做的很简单的计算器,基本运算都有,可报错
单片机源程序如下:
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include "Shuzi.h"
#include "Character.h"
#include "Define.h"
void Delayms(void){
unsigned int n = 0x00;
for(n=2000;n>0;n--);
}
void Delays(unsigned int n){
unsigned int m = 0x00;
while(n--){
for(m=0;m<500;m++){
;
}
}
}
//向上边LCD还是向下边LCD写数据/命令
void LCD_Write(unsigned char chn,unsigned char CMD_DAT,unsigned char dat){
unsigned char n = 0x00;
if(CMD_DAT == COMMAND){
LCD_RS_OUT0;
}else{
LCD_RS_OUT1;
}
LCD_DATA_PORT = dat;
LCD_WR_OUT0;
LCD_RD_OUT0;
if (chn == LCD_UP){//选择上边LCD
LCD_CS1_OUT0;
}else{
if(chn == LCD_DOWN){//选择下边LCD
LCD_CS2_OUT0;
}else{//选择两个LCD
LCD_CS1_OUT0;
LCD_CS2_OUT0;
}
}
for(n=0;n<10;n++);
LCD_RD_OUT1;
for(n=0;n<10;n++);
//LCD_WR_OUT1;
if (chn == LCD_UP){//选择上边LCD
LCD_CS1_OUT1;
}else{
if(chn == LCD_DOWN){//选择下边LCD
LCD_CS2_OUT1;
}else{//选择两个LCD
LCD_CS1_OUT1;
LCD_CS2_OUT1;
}
}
LCD_RD_OUT0;
for(n=0;n<10;n++);
}
//在com,seg上写一个字节的数据
void Draw_Line(unsigned char chn,unsigned char pg,unsigned char seg,unsigned char dat1,unsigned char dat2,unsigned char CNT){
unsigned char n = 0x00;
//unsigned char m = 0x00;
seg = seg +4;
LCD_Write(chn,COMMAND,(0xb0 | pg ));// 写 pg 地址
LCD_Write(chn,COMMAND,(0x10 | (((seg >> 4) & 0x0f))));// 写 seg 高4位地址
LCD_Write(chn,COMMAND,(0x00 | ((seg & 0x0f))));// 写 seg 低4位地址
for(n=0;n<CNT;n++){
LCD_Write(chn,DATA,dat1);
n++;
if(n<CNT){
//for(m=0;m<5;m++);
LCD_Write(chn,DATA,dat2);
//for(m=0;m<5;m++);
}
}
}
//清除LCD上所有的数据,使之显示空白
void Clear_LCD(unsigned char chn){
unsigned int n = 0x00;
for(n=0;n<LCD_HEIGHT_PAGE;n++){
Draw_Line(chn,n,0x00,0x00,0x00,LCD_WIDTH);
}
}
//初始化LCD
void LCD_Init(void){
LCD_RST_OUT0;
Delays(50);
LCD_RST_OUT1;
Delays(50);
//LCD_Write(LCD_TWO,COMMAND,0xa0);//
LCD_Write(LCD_TWO,COMMAND,0xc0);
LCD_Write(LCD_TWO,COMMAND,0xa1);//
//LCD_Write(LCD_TWO,COMMAND,0xc8);
LCD_Write(LCD_TWO,COMMAND,0xf8);
LCD_Write(LCD_TWO,COMMAND,0x00);
LCD_Write(LCD_TWO,COMMAND,0xa2);
Delays(10);
LCD_Write(LCD_TWO,COMMAND,0x2c);
Delays(10);
LCD_Write(LCD_TWO,COMMAND,0x2e);
Delays(10);
LCD_Write(LCD_TWO,COMMAND,0x2f);
Delays(10);
LCD_Write(LCD_TWO,COMMAND,0x24);
Delays(10);
LCD_Write(LCD_TWO,COMMAND,0x81);
LCD_Write(LCD_TWO,COMMAND,41);// 41 = 9.0V
Delays(10);
LCD_Write(LCD_TWO,COMMAND,0x40);
Clear_LCD(LCD_UP);
Clear_LCD(LCD_DOWN);
LCD_Write(LCD_TWO,COMMAND,0xaf);
Delays(10);
}
//清除数字区
void Clear_Num(unsigned char pg,unsigned char seg,unsigned char length){
Draw_Line(LCD_UP,pg,seg,0x00,0x00,length);
Draw_Line(LCD_UP,pg+1,seg,0x00,0x00,length);
}
//冀雅测试画面
void Show_Test(unsigned char chn){
unsigned char n = 0x00;
unsigned char m = 0x00;
for(n=0;n<TEST_CNT;n++){
for(m=0;m<LCD_HEIGHT_PAGE;m++){
Draw_Line(chn,m,0x00,TEST_CODE[n*2],TEST_CODE[n*2+1],LCD_WIDTH);
}
Delays(TEST_DELAY_VALUE);
}
}
//显示框屏
void Show_Kuang(unsigned char chn){
unsigned char n = 0x00;
Draw_Line(chn,0,0x00,0x01,0x01,LCD_WIDTH);
Draw_Line(chn,(LCD_HEIGHT_PAGE - 1),0x00,0x80,0x80,LCD_WIDTH);
for(n=0;n<LCD_HEIGHT_PAGE;n++){
Draw_Line(chn,n,0,0xff,0xff,0x01);
Draw_Line(chn,n,(LCD_WIDTH - 1),0xff,0xff,0x01);
}
}
//显示冀雅模块汉字
void Show_Hanzi(unsigned char chn,unsigned char pg,unsigned char seg,unsigned char color){
unsigned int n = 0x0000;
unsigned int m = 0x0000;
unsigned int k = 0x0000;
for(k=0;k<4;k++){
for(n=0;n<2;n++){
for(m=0;m<16;m++){
if(color == BLACK){
Draw_Line(chn,pg+n,seg+k*16+m,JIYA[k*32+n*16+m],0x00,0x01);
}else{
Draw_Line(chn,pg+n,seg+k*16+m,~JIYA[k*32+n*16+m],0x00,0x01);
}
}
}
}
}
//显示+-*/ 标志触摸区
// ADD_FUHAO 0
// MIN_FUHAO 1
// MUL_FUHAO 2
// DIV_FUHAO 3
void Show_Fuhao(unsigned char chn,unsigned char witch,unsigned char pg,unsigned char seg){
unsigned char n = 0x00;
unsigned char m = 0x00;
if(witch != 0xff){//如果不是清屏命令
for(n=0;n<2;n++){
for(m=0;m<17;m++){
Draw_Line(chn,pg+n,seg+m,YUN_SUN_CODE[witch*34+n*17+m],0x00,0x01);
}
}
}else{
for(n=0;n<2;n++){
Draw_Line(chn,pg+n,seg,0x00,0x00,17);
}
}
}
//显示单一字符,数字,或者+-*/=C功能按键符号
void Show_Sig_Char(unsigned char chn,unsigned char pg,unsigned char seg,unsigned char num){
unsigned char n = 0x00;
unsigned char m = 0x00;
if(num < 10){//如果是数字
for(n=0;n<2;n++){
for(m=0;m<9;m++){
Draw_Line(chn,pg+n,seg+m,MID_NUM_CODE[num*18+n*9+m],0x00,0x01);
}
}
}else{
switch(num){
case 'C':
Show_CLR_CAL_FUHAO(chn,CLR_FUHAO,pg,seg);
break;
case '=':
Show_CLR_CAL_FUHAO(chn,CAL_FUHAO,pg,seg);
break;
case '+':
Show_Fuhao(chn,ADD_FUHAO,pg,seg);
break;
case '-':
Show_Fuhao(chn,MIN_FUHAO,pg,seg);
break;
case '*':
Show_Fuhao(chn,MUL_FUHAO,pg,seg);
break;
case '/':
Show_Fuhao(chn,DIV_FUHAO,pg,seg);
break;
default:
break;
}
}
}
//显示数字,long型数据,最多可显示10位数字
void Show_Num(unsigned char chn,unsigned char pg,unsigned char seg,unsigned long num){
unsigned long dat[10];
unsigned long tmp = 0x00000000;
unsigned char dispay_on = 0x00;
unsigned char n = 0x00;
unsigned char m = 0x00;
unsigned char k = 0x00;
tmp = num;
dat[0] = tmp / 1000000000;
dat[1] = (num - dat[0] * 100000000) / 100000000;
dat[2] = (num - dat[0] * 1000000000 - dat[1] * 100000000) / 10000000;
dat[3] = (num - dat[0] * 1000000000 - dat[1] * 100000000 - dat[2] * 10000000) / 1000000;
dat[4] = (num - dat[0] * 1000000000 - dat[1] * 100000000 - dat[2] * 10000000 - dat[3] * 1000000) / 100000;
dat[5] = (num - dat[0] * 1000000000 - dat[1] * 100000000 - dat[2] * 10000000 - dat[3] * 1000000 - dat[4] * 100000) / 10000;
dat[6] = (num - dat[0] * 1000000000 - dat[1] * 100000000 - dat[2] * 10000000 - dat[3] * 1000000 - dat[4] * 100000 - dat[5] * 10000) / 1000;
dat[7] = (num - dat[0] * 1000000000 - dat[1] * 100000000 - dat[2] * 10000000 - dat[3] * 1000000 - dat[4] * 100000 - dat[5] * 10000 - dat[6] * 1000) / 100;
dat[8] = (num - dat[0] * 1000000000 - dat[1] * 100000000 - dat[2] * 10000000 - dat[3] * 1000000 - dat[4] * 100000 - dat[5] * 10000 - dat[6] * 1000 - dat[7] * 100) / 10;
dat[9] = num % 10;
for(n=0;n<10;n++){//显示10个数字
if(dat[n] != 0x00){//数字不等于0,需要显示
dispay_on = 0xff;
Show_Sig_Char(chn,pg,seg+n*9,dat[n]);
}else{
if(dispay_on != 0x00){//已经有不为0的数字了,需要继续显示
Show_Sig_Char(chn,pg,seg+n*9,dat[n]);
}else{
if(n == 9){
Show_Sig_Char(chn,pg,seg+n*9,dat[n]);
}
}
}
}
}
//显示输入的数字,最多5个数字
void Show_Input_Num(unsigned char pg,unsigned char seg,unsigned char dat[5]){
unsigned char n = 0x00;
unsigned char dispay_on = 0x00;
for(n=0;n<5;n++){
if(dat[n] != 0x00){//数字不等于0,需要显示
dispay_on = 0xff;
Show_Sig_Char(LCD_UP,pg,seg+n*9,dat[n]);
}else{
if(dispay_on != 0x00){//已经有不为0的数字了,需要继续显示
Show_Sig_Char(LCD_UP,pg,seg+n*9,dat[n]);
}
}
}
}
//开始SEG = 30
//
void Show_First_Num(unsigned char num){
if(num > 9){
}
}
//显示计算器界面,下边的屏幕
void Show_CAL_GUI(void ){
unsigned char n = 0x00;
for(n=0;n<16;n++){
Show_Sig_Char(LCD_DOWN,CAL_POSITION_GUI[n*2],CAL_POSITION_GUI[n*2+1],TP_KEY_CODE[n]);
}
}
const unsigned int MUL_CODE[]={
10000,1000,100,10,1,
};
//计算输入值
unsigned long CAL_Input_Num(unsigned char num[5]){
unsigned long tmpl = 0x00;
unsigned long dt = 0x00;
unsigned char n = 0x00;
tmpl = 0x00000000;
for(n=0;n<5;n++){
dt = num[n];
dt = dt * MUL_CODE[n];
tmpl = tmpl + dt;
}
return tmpl;
}
//显示 作者
void Show_Author(unsigned char pg,unsigned char seg){
unsigned char n = 0x00;
unsigned char m = 0x00;
unsigned char k = 0x00;
for(k=0;k<6;k++){
for(n=0;n<2;n++){
for(m=0;m<16;m++){
Draw_Line(LCD_UP,pg+n,seg+k*16+m,AUTHOR_CODE[k*32+n*16+m],0x00,0x01);
}
}
}
}
//显示 冀雅
void Show_Jiya(unsigned char pg,unsigned char seg){
unsigned char n = 0x00;
unsigned char m = 0x00;
unsigned char k = 0x00;
for(k=0;k<2;k++){
for(n=0;n<2;n++){
for(m=0;m<16;m++){
Draw_Line(LCD_UP,pg+n,seg+k*16+m,JIYA[k*32+n*16+m],0x00,0x01);
}
}
}
}
//显示 计算器
void Show_Jisuanqi(unsigned char pg,unsigned char seg){
unsigned char n = 0x00;
unsigned char m = 0x00;
unsigned char k = 0x00;
for(k=0;k<3;k++){
for(n=0;n<2;n++){
for(m=0;m<16;m++){
Draw_Line(LCD_UP,pg+n,seg+k*16+m,JISUANQI_CODE[k*32+n*16+m],0x00,0x01);
}
}
}
}
//显示 参数错误
void Show_Err_Tips(unsigned char pg,unsigned char seg){
unsigned char n = 0x00;
unsigned char m = 0x00;
unsigned char k = 0x00;
for(k=0;k<4;k++){
for(n=0;n<2;n++){
for(m=0;m<16;m++){
Draw_Line(LCD_UP,pg+n,seg+k*16+m,ERROR_TIPS[k*32+n*16+m],0x00,0x01);
}
}
}
}
//在上边屏幕显示冀雅LOGO
void Show_Logo(void ){
Show_Jiya(0,8);//显示冀雅
Show_Jisuanqi(3,0);//显示计算器
}
//计算器测试
void Caculate_Test(void ){
unsigned char Loop = 0x01;
unsigned char key = 0x00;
unsigned char Input_Num_Cnt = 0x00;
unsigned char Input_NUM[5];
unsigned char Fuhao = 0xff;
unsigned char n = 0x00;
unsigned char tmpm = 0x00;
unsigned char last_key = 0xff;
unsigned long rslt = 0x00;
First_NUM = 0x00000000;
Second_NUM= 0x00000000;
for(n=0;n<5;n++){
Input_NUM[n] = 0x00;
}
Clear_LCD(LCD_UP);//清屏上边的屏幕
Clear_LCD(LCD_DOWN);//清屏下边的屏幕
Show_Logo();//显示冀雅LOGO
Show_CAL_GUI();//显示下边屏幕的数字排列和符号标示
Input_Num_Cnt = 0x00;
while(Loop == 0x01){//进入有条件无限循环
key = TP_Scan();//扫描按键
if(key != 0xff){//如果有按键按下
switch(key){//判断按下的是哪个按键
case '+':
Show_Fuhao(LCD_UP,ADD_FUHAO,2,55);
Fuhao = '+';
Input_Num_Cnt = 0x00;
for(n=0;n<5;n++){
Input_NUM[n] = 0x00;
}
break;
case '-':
Show_Fuhao(LCD_UP,MIN_FUHAO,2,55);
Fuhao = '-';
Input_Num_Cnt = 0x00;
for(n=0;n<5;n++){
Input_NUM[n] = 0x00;
}
break;
case '*':
Show_Fuhao(LCD_UP,MUL_FUHAO,2,55);
Fuhao = '*';
Input_Num_Cnt = 0x00;
for(n=0;n<5;n++){
Input_NUM[n] = 0x00;
}
break;
case '/':
Show_Fuhao(LCD_UP,DIV_FUHAO,2,55);
Fuhao = '/';
Input_Num_Cnt = 0x00;
for(n=0;n<5;n++){
Input_NUM[n] = 0x00;
}
break;
case 'C':
for(n=0;n<5;n++){//数据清零
Input_NUM[n] = 0x00;
}
First_NUM = 0x00000000;
Second_NUM= 0x00000000;
Input_Num_Cnt = 0x00;
Fuhao = 0xff;
Clear_Num(0,80,45);//清除第一个数字
Clear_Num(3,80,45);//清除第二个数字
Clear_Num(6,36,90);//清除计算结果
Show_Fuhao(LCD_UP,0xff,2,55);//清除符号区
Clear_Num(6,20,9);//清除 " = "
break;
case '=':
//Second_NUM = CAL_Input_Num(Input_NUM);
Show_Sig_Char(LCD_UP,6,20,'=');
switch(Fuhao){//根据符号做出不同处理;
case '+':
rslt = First_NUM + Second_NUM;
break;
case '-':
rslt = First_NUM - Second_NUM;
break;
case '*':
rslt = First_NUM * Second_NUM;
break;
case '/':
if(Second_NUM != 0x00){
rslt = First_NUM / Second_NUM;
}else{//有错误
Clear_LCD(LCD_UP);//
for(n=0;n<3;n++){
Show_Err_Tips(3,32);//显示参数错误
Delays(100);
Clear_LCD(LCD_UP);//
Delays(100);
}
Loop = 0x00;//从此函数返回去
}
break;
default:
/*
Clear_LCD(LCD_UP);//
for(n=0;n<3;n++){
Show_Err_Tips(3,32);//显示参数错误
Delays(100);
Clear_LCD(LCD_UP);//
Delays(100);
}
Loop = 0x00;//从此函数返回去
*/
break;
}
Show_Num(LCD_UP,6,36,rslt);//显示计算结果
//重新初始化所有参数
Input_Num_Cnt = 0x00;
for(n=0;n<5;n++){
Input_NUM[n] = 0x00;
}
First_NUM = 0x00000000;
Second_NUM= 0x00000000;
Input_Num_Cnt = 0x00;
Fuhao = 0xff;
break;
default://输入的是0——9数字
if(last_key == '='){//如果按数字时,之前有计算结果显示,则清除之,再正常显示
for(n=0;n<5;n++){//数据清零
Input_NUM[n] = 0x00;
}
First_NUM = 0x00000000;
Second_NUM= 0x00000000;
Input_Num_Cnt = 0x00;
Fuhao = 0xff;
Clear_Num(0,80,45);//清除第一个数字
Clear_Num(3,80,45);//清除第二个数字
Clear_Num(6,36,90);//清除计算结果
Show_Fuhao(LCD_UP,0xff,2,55);//清除符号区
Clear_Num(6,20,9);//清除 " = "
}//完成准备工作
if(Fuhao == 0xff){//输入第一个数据
//判断输入的数据
if(Input_Num_Cnt < 5){//输入的不够5个数字
for(n=0;n<4;n++){
Input_NUM[n] = Input_NUM[n+1];
}
Input_NUM[4] = key;
Input_Num_Cnt++;
}
Show_Input_Num(0,80,Input_NUM);
First_NUM = CAL_Input_Num(Input_NUM);
}else{//输入第二个数据
if(Input_Num_Cnt < 5){//输入的不够5个数字
for(n=0;n<4;n++){
Input_NUM[n] = Input_NUM[n+1];
}
Input_NUM[4] = key;
Input_Num_Cnt++;
}
Show_Input_Num(3,80,Input_NUM);
Second_NUM = CAL_Input_Num(Input_NUM);
}
break;
}
last_key = key;//记录最后一次的按键
}
}
}
void Start_LED(void ){
unsigned char n = 0x00;
for(n=0;n<1;n++){
OPEN_LED;
Delays(100);
CLOSE_LED;
//Delays(100);
}
}
void main(void)
{
// M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
// Insert your main routine code here.
unsigned char n = 0x00;
unsigned char Flash_CNT= 50;
unsigned char Wait_LED = 0x00;
unsigned char Pre_Key = 0x00;
unsigned char Valid_Key;
unsigned char Valid_CNT = 0x00;
unsigned char KEY_STATE[SENSOR_CNT];
for(n=0;n<SENSOR_CNT;n++){
KEY_STATE[n] = KEY_RELEASE;
Valid_Key = 0x00;
}
LCD_Init();//初始化LCD
Delays(5);
Capsense_Init();//初始化Capsense
Start_LED();
/*
for(n=0;n<2;n++){
Show_Test(LCD_TWO);
Clear_LCD(LCD_TWO);
Show_Kuang(LCD_TWO);
Delays(TEST_DELAY_VALUE);
Clear_LCD(LCD_TWO);
Show_Hanzi(LCD_TWO,1,32,BLACK);
Show_Hanzi(LCD_TWO,5,32,WHITE);
Delays(TEST_DELAY_VALUE);
}
*/
while(1){
Caculate_Test();
}
}
复制代码
所有资料51hei提供下载:
Calcu.rar
(3.72 KB, 下载次数: 5)
2017-12-22 23:15 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1