你这,能搭话的就少了啊我反正是看不明白 |
不明觉历! |
白无无 发表于 2023-9-4 07:46 咱们不是在讨论低矮歪吗?只要愿意去动手做的,肯迈出实践的第一步,就成功了一半。 |
江东老歌 发表于 2023-9-4 08:25 我朋友仍然用汇编。汇编编译出来的,文件个头都比C小很多,运行效率也高。你们才是高手。 我问我那朋友,汇编可读性差,你编着不费劲?人家说习惯就好,就像平时说话一样了。 |
DianGongN 发表于 2023-9-4 08:10 谈不上啊,特备是电,真的业余水平,玩玩就好。 |
专业技术贴,比我们以前用汇编语言方便多了! |
大侠水平高啊,机电通吃妥妥的。 |
//这是一个用于测量自行车车速、里程的程序,需要专门设计的硬件支持。 //电路包含几大部分:脉冲采样、DS1302以及89S52,5位LED数码管显示。 #include <reg52.h> #include<intrins.h> // 0 1 2 3 4 5 6 7 8 9 空 //码表,不带小数点,最后两位为显示空和- unsigned char code table[] = {0x77,0x14,0xb3,0xb6,0xd4,0xe6,0xe7,0x34,0xf7,0xf6,0x00,0x80}; unsigned char code table_D[] = {0x7f,0x1c,0xbb,0xbe,0xdc,0x6d,0xee,0x3c,0xff,0xfe,0x00,0x02,0x82,0xa2,0x80};//码表,带小数点。 unsigned long z=4294967295; // 2毫秒的个数 unsigned int time=65535,dc = 0; unsigned int maxg,maxs,maxb,maxq,maxw,v,max; // 最后两个是速度 和 最高车速 unsigned char gn = 1; // 功能切换 unsigned char g,s,b,q,w,temp,xhcs; //显示推送位 unsigned long sg,ss,sb,sq,sw,ssw; sbit ACC0 = ACC^0; sbit ACC7 = ACC^7; sbit T_CLK = P1^6; //实时时钟时钟线引脚 sbit T_IO = P1^5; //实时时钟数据线引脚 sbit T_RST = P1^7; //实时时钟复位线引脚 sbit p11 = P1^1; sbit p10 = P1^0; bit dw=1; // ************************************************************************************************************** // * 名 称:delay(void) * // * 功 能:延迟 * // * 输 入:无 * // * 输 出:无 * // ************************************************************************************************************** void delay(void) { unsigned char x,j; for(j=0;j<2;j++) for(x=0;x<=148;x++); } // ************************************************************************************************************** // * 名 称:v_RTInputByte() * // * 功 能:往DS1302写入1Byte数据 * // * 输 入:ucDa 写入的数据 * // * 输 出:无 * // ************************************************************************************************************** void v_RTInputByte(unsigned char ucDa) { unsigned char i; ACC = ucDa; T_RST = 1; for(i=8; i>0; i--) { T_IO = ACC0; T_CLK = 1; T_CLK = 0; ACC = ACC >> 1; } } // ************************************************************************************************************** // * 名 称:uc_RTOutputByte() * // * 功 能:从DS1302读取1Byte数据 * // * 输 入:无 * // * 返回值:ACC * // ************************************************************************************************************** unsigned char uc_RTOutputByte(void) { unsigned char i; T_RST = 1; for(i=8; i>0; i--) { ACC = ACC >>1; T_IO=1; ACC7 = T_IO; T_CLK = 1; T_CLK = 0; } return(ACC); } // ************************************************************************************************************** // * 名 称:v_W1302(unsigned char ucAddr, unsigned char ucDa) * // * 功 能:往DS1302写入数据 * // * 输 入:ucAddr: DS1302地址, ucDa: 要写的数据 * // * 返回值:无 * // ************************************************************************************************************** void v_W1302(unsigned char ucAddr, unsigned char ucDa) { T_RST = 0; T_CLK = 0; T_RST = 1; v_RTInputByte(ucAddr); // 写地址 _nop_(); _nop_(); v_RTInputByte(ucDa); // 写1Byte数据 T_CLK = 1; T_RST = 0; } // ************************************************************************************************************** // * 名 称:uc_R1302(unsigned char ucAddr) * // * 功 能:读取DS1302某地址的数据 * // * 输 入:ucAddr: DS1302地址 * // * 返回值:ucDa :读取的数据 * // ************************************************************************************************************** unsigned char uc_R1302(unsigned char ucAddr) { unsigned char ucDa; T_RST = 0; T_CLK = 0; T_RST = 1; v_RTInputByte(ucAddr); //写地址,命令 _nop_(); _nop_(); ucDa = uc_RTOutputByte(); //读1Byte数据 T_CLK = 1; T_RST = 0; return(ucDa); } // ************************************************************************************************************** // * 名称 : bcdtodec(unsigned char bcd) * // * 功能 : BCD码转换为DEC码 * // * 输入 : bcd码 * // * 输出 : dec码 * // ************************************************************************************************************** unsigned char bcdtodec(unsigned char bcd) { unsigned char data1; data1 = bcd & 0x0f; //取BCD低4位 bcd = bcd & 0x70; //剔除BCD的最高位和低4位。 data1 += bcd >> 1; data1 += bcd >> 3; //用位移代替乘法运算 return data1; } void lc() { unsigned long x,y; x = sg + ss*10 + sb*100 + sq*1000 + sw*10000 + ssw*100000; x = x*41/200; if(x == 487805) { x=0; xhcs++; } x = x % 100000; w = x / 10000; if (x < 10000)w=10; y = x % 10000; q = y / 1000; //求四位数的千位 if (x < 1000)q=10; y = y % 1000; //求四位数去除千位的值 b = y / 100; //求四位数的百位 y = y % 100; //求四位数去除千位后再去除百位的值 s = y / 10; //求四位数的十位 g = y % 10; //求四位数的个位 } void dlc() { unsigned long x,y; x = dc*41/200; x = x % 100000; w = x / 10000; if (x < 10000)w=10; y = x % 10000; q = y / 1000; //求四位数的千位 if (x < 1000)q=10; y = y % 1000; //求四位数去除千位的值 b = y / 100; //求四位数的百位 y = y % 100; //求四位数去除千位后再去除百位的值 s = y / 10; //求四位数的十位 g = y % 10; //求四位数的个位 } void ljlc(void) { if(sg > 9) { sg = 0; ss++; } if(ss == 10) { ss = 0; sb++; } if(sb == 10) { sb = 0; sq++; } if(sq == 10) { sq = 0; sw++; } if(sw == 10) { sw = 0; ssw++; } if(ssw == 10) { ssw = 0; } } void readdata() { //******************************************************************* //最高速 v_W1302(0x8f,0); maxg = bcdtodec(uc_R1302(0xc1)); //读出DS1302中的maxg v_W1302(0x8f,0); maxs = bcdtodec(uc_R1302(0xc3)); //读出DS1302中的maxs v_W1302(0x8f,0); maxb = bcdtodec(uc_R1302(0xc5)); //读出DS1302中的maxb v_W1302(0x8f,0); maxq = bcdtodec(uc_R1302(0xc7)); //读出DS1302中的maxq v_W1302(0x8f,0); maxw = bcdtodec(uc_R1302(0xc9)); //读出DS1302中的maxw //******************************************************************* //总里程 v_W1302(0x8f,0); sg = bcdtodec(uc_R1302(0xcb)); //读出DS1302中的sg v_W1302(0x8f,0); ss = bcdtodec(uc_R1302(0xcd)); //读出DS1302中的ss v_W1302(0x8f,0); sb = bcdtodec(uc_R1302(0xcf)); //读出DS1302中的sb v_W1302(0x8f,0); sq = bcdtodec(uc_R1302(0xd1)); //读出DS1302中的sq v_W1302(0x8f,0); sw = bcdtodec(uc_R1302(0xd3)); //读出DS1302中的sw v_W1302(0x8f,0); ssw = bcdtodec(uc_R1302(0xd5)); //读出DS1302中的ssw //******************************************************************* //循环次数 v_W1302(0x8f,0); xhcs = bcdtodec(uc_R1302(0xd7)); //读出DS1302中的xhcs } void savedata(void) { //***************************************************************************** // 最高车速 v_W1302(0x8e,0); v_W1302(0xc0,maxg); v_W1302(0x8e,0); v_W1302(0xc2,maxs); v_W1302(0x8e,0); v_W1302(0xc4,maxb); v_W1302(0x8e,0); v_W1302(0xc6,maxq); v_W1302(0x8e,0); v_W1302(0xc8,maxw); //***************************************************************************** // 总里程 v_W1302(0x8e,0); v_W1302(0xca,sg); v_W1302(0x8e,0); v_W1302(0xcc,ss); v_W1302(0x8e,0); v_W1302(0xce,sb); v_W1302(0x8e,0); v_W1302(0xd0,sq); v_W1302(0x8e,0); v_W1302(0xd2,sw); v_W1302(0x8e,0); v_W1302(0xd4,ssw); //***************************************************************************** //循环次数 v_W1302(0x8e,0); v_W1302(0xd6,xhcs); } void ql() { //***************************************************************************** // 最高车速 v_W1302(0x8e,0); v_W1302(0xc0,0); v_W1302(0x8e,0); v_W1302(0xc2,0); v_W1302(0x8e,0); v_W1302(0xc4,0); v_W1302(0x8e,0); v_W1302(0xc6,0); v_W1302(0x8e,0); v_W1302(0xc8,0); //***************************************************************************** // 总里程 v_W1302(0x8e,0); v_W1302(0xca,0); v_W1302(0x8e,0); v_W1302(0xcc,0); v_W1302(0x8e,0); v_W1302(0xce,0); v_W1302(0x8e,0); v_W1302(0xd0,0); v_W1302(0x8e,0); v_W1302(0xd2,0); v_W1302(0x8e,0); v_W1302(0xd4,0); //***************************************************************************** //循环次数 v_W1302(0x8e,0); v_W1302(0xd6,0); } void clock() { unsigned char min, hour; v_W1302(0x8f, 0); min = bcdtodec(uc_R1302(0x83)); //读出DS1302中的分 v_W1302(0x8f, 0); hour = bcdtodec(uc_R1302(0x85)); //读出DS1302中的小时 w = hour/10; q = hour%10; b = 14; s = min/10; g = min%10; } void xh(void) { g = xhcs%100; if(g<10)s = 10;else s = g / 10; g = g % 10; b = 10; q = 10; w = 10; } void display(void) { P2=0x01; P0=table[w]; delay(); P0=0x00; P2=0x02; P0=table[q]; delay(); P0=0x00; P2=0x04; P0=table_D[b]; delay(); P0=0x00; P2=0x08; P0=table[g]; delay(); P0=0x00; P2=0x10; P0=table[s]; delay(); P0=0x00; } void tim(void) interrupt 1 using 1 { TH0=0xf0;//重新赋值,定时2毫秒 TL0=0x5f; time++;//计时,数2毫秒的个数zs(); } void ISR_INT0(void) interrupt 0 using 1 { sg++; dc++; z=time;//车轮转动1圈所用的时间--------多少个2毫秒 time=0;//计时复零 } void adjust(void) { unsigned char min,sec; v_W1302(0x8f, 0); sec = bcdtodec(uc_R1302(0x81)); //读出DS1302中的秒 v_W1302(0x8f, 0); min = bcdtodec(uc_R1302(0x83)); //读出DS1302中的分 w = min/10; q = min%10; b = 10; s = sec/10; g = sec%10; if(p10 == 0) { if(sec > 29) { v_W1302(0x8e,0); v_W1302(0x80,0x59); //写入秒sec = 59; } else { v_W1302(0x8e,0); v_W1302(0x80,0x00); //写入秒sec = 00; } } } void jscs(void) { unsigned long ls; v = 369000/z; if(v > max)max = v; if(v < 6)v = 0; maxw = max/10000; ls = max%10000; maxq = ls/1000; ls = ls%1000; maxb = ls/100; ls = ls%100; maxs = ls/10; maxg =ls%10; } void cs(void) { unsigned long ls; if(v > 9999)w = v/10000;else w=10; ls = v%10000; if(ls > 999)q = ls/1000;else q=10; ls = ls%1000; b = ls/100; ls = ls%100; s = ls/10; g = ls%10; } void maxcs(void) { unsigned long ls; if(max > 9999)w = max/10000;else w=10; ls = max%10000; if(ls > 999)q = ls/1000;else q=10; ls = ls%1000; b = ls/100; ls = ls%100; s = ls/10; g = ls%10; } /******************************************************************** * 名称 : Write_DS1302Init() * 功能 : 往DS1302中写入数据。最开始显示的数据就是在这里设置的。 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void Write_DS1302Init(void) { v_W1302(0x8e,0); v_W1302(0x80,0x00); //写入秒 v_W1302(0x8e,0); v_W1302(0x82,0x09); //写入分 v_W1302(0x8e,0); v_W1302(0x84,0x18); //写入小时 v_W1302(0x8e,0); v_W1302(0x86,0x18); //写入日 v_W1302(0x8e,0); v_W1302(0x88,0x06); //写入月 v_W1302(0x8e,0); v_W1302(0x8a,0x01); //写入星期 v_W1302(0x8e,0); v_W1302(0x8c,0x18); //写入年 } void ljsj(void) {} void main(void) { unsigned char xd=0,q; EX0 = 1;//外部中断0设置 IT0 = 1; EX1 = 1;//外部中断1设置 IT1 = 1; //定时器设置 2ms in 24M crystal,工作方式1,16位计数器,2毫秒4000个脉冲故(65536-4000)的16进制为f05f。 TMOD |= 0x01; TH0 = 0xf0; TL0 = 0x5f; ET0 = 1; //打开中断 TR0 = 1; EA = 1; v_W1302(0x8e,0);//打开写保护 // v_W1302(0x90,0x00); // TCS 4位 DS 2位 TS 2位 // xxxx xx xx // 1010可以充电 01一个二极管 00无电阻 // 其他禁止充电 10两个二极管 01 2K电阻 // 其他禁止充电 10 4K电阻 // 11 8K电阻 //如果以1个二极管串联4K电阻充电,则为:10100110 十六进制为:0xa6 // Write_DS1302Init(); if (p11 == 0) //检测是否按下按钮,在系统加电时按下按钮,则执行清零程序 { ql(); for(q=0;q<255;q++) delay(); for(q=0;q<255;q++) delay(); } readdata(); //读出DS1302内的数据 max = maxg + maxs*10 + maxb*100 + maxq*1000 + maxw*10000; //计算以前的最高车速 while(1) { if (p11 == 0 & xd == 0) //检测是否按下按钮 { gn++; //如果按下按键则转换功能 if(gn > 7)gn = 1; xd = 1; //如果没有松开按键不允许继续转换 for(q=0;q<255;q++) delay(); for(q=0;q<255;q++) delay(); if(p11 == 1)xd = 0; } jscs(); //计算车速 ljlc(); //累计里程 if(time < 2500)ljsj(); //如果时间小于5秒(行车中)则执行累积时间 else if(time <3000) { time = 65530; savedata(); //否则认为已停车,保存数据 z = time; } else time = 65530; //保持time=3500,不至于育溢出 switch(gn) { case 1:clock();break; //时钟 case 2:cs();break; //车速 case 3:dlc();break; //当前里程 case 4:lc();break; //总里程 case 5:xh();break; //总里程数 case 6:maxcs();break; //最高车速 case 7:adjust();break; //对表 } display(); } } |
小黑屋|手机版|Archiver|机械必威体育网址 ( 京ICP备10217105号-1,京ICP证050210号,浙公网安备33038202004372号 )
GMT+8, 2025-1-11 04:51 , Processed in 0.063711 second(s), 21 queries , Gzip On.
Powered by Discuz! X3.4 Licensed
© 2001-2017 Comsenz Inc.