找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1650|回复: 4
打印 上一主题 下一主题
收起左侧

单片机程序是对脉冲进行计数,然后从lcd显示出来,但就是显示不正确 求帮助

[复制链接]
跳转到指定楼层
楼主
ID:839532 发表于 2021-5-11 22:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>
#include<intrins.h>
#include<math.h>
#define uint unsigned int
#define uchar unsigned char
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P2
sbit RS = P3^0; //定义端口 (显示屏)
sbit RW = P3^1;
sbit EN = P3^2;
void LCD_Init(void);
void inti()
{ LCD_Init() ;
TMOD=0x05 ;//*T0为16位计数方式*/
TH0=F0 ;
TL0=60 ;//*预置初值*/
TR0=1;
}
// 单片机计算脉冲数 显示
uint num;//计数变量声明
/*延时子程序*******************************************************/
void delay(uint xms)
{
uint j;
for(;xms>0;xms--)
for(j=110;j>0;j--);
}
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
DataPort= 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
//while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_CLR;
RW_CLR;
EN_SET;
DataPort= com;
_nop_();
EN_CLR;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
//while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x); //表示第一行
}
else
{
LCD_Write_Com(0xC0 + x); //表示第二行
}
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
/*------------------------------------------------
初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
/*主程序***************************************************************/
void main()
{
inti();
while(1)
{
float num1,num2,num;
unsigned char x;
unsigned char y;
unsigned char Data;
Data=TH0*255+TL0;//读计数器数据
if(Data==4000){TH0=F0;TL0=60;TR0=0;} //计满清零
num1=Data/4*0.05;
num2=0.05/4*(Data%4);
num=num1+num2;
LCD_Write_Char(x,y,num);
}
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:65956 发表于 2021-5-12 08:22 | 只看该作者
虽然没有附上实际运行结果图,但按个人经验来看,我认为你计算器应采用中断方式进入计数,而显示放在主函数中运行,这样才能保证计数后送显示的及时性和正确性,如果按你现在计数及显示都在主函数处理,你会发现计数值比你显示的快得多,因为显示需要的时间远远大于计数,除非你的计数是HZ速度,如果是KHZ的速度,显示会来不及显示,所以计数值会比显示快,也就是你说的不对,只是想法,希望对你有帮助
回复

使用道具 举报

板凳
ID:213173 发表于 2021-5-12 10:48 | 只看该作者
脉冲频率不太高可以用这个方式计数。你的计数和数据处理有点问题,不清楚你要显示实际数还是比例数,按需自行修改。
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include<math.h>
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. #define RS_CLR RS=0
  7. #define RS_SET RS=1
  8. #define RW_CLR RW=0
  9. #define RW_SET RW=1
  10. #define EN_CLR EN=0
  11. #define EN_SET EN=1
  12. #define DataPort P0
  13. sbit RS = P3^0; //定义端口 (显示屏)
  14. sbit RW = P3^1;
  15. sbit EN = P3^2;
  16. uchar data dis_buf[]="0000";

  17. void LCD_Init(void);

  18. void inti()
  19. {
  20.         LCD_Init() ;
  21.         TMOD=0x05 ;//*T0为16位计数方式*/
  22.         TH0=F0 ;
  23.         TL0=60 ;//*预置初值*/
  24.         TR0=1;
  25. }
  26. // 单片机计算脉冲数 显示
  27. //uint num;//计数变量声明
  28. /*延时子程序*******************************************************/
  29. /*
  30. void delay(uint xms)
  31. {
  32.         uint j;
  33.         for(;xms>0;xms--)
  34.                 for(j=110;j>0;j--);
  35. }*/
  36. /*------------------------------------------------
  37. uS延时函数,含有输入参数 unsigned char t,无返回值
  38. unsigned char 是定义无符号字符变量,其值的范围是
  39. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  40. 长度如下 T=tx2+5 uS
  41. ------------------------------------------------*/
  42. void DelayUs2x(unsigned char t)
  43. {
  44. while(--t);
  45. }
  46. /*------------------------------------------------
  47. mS延时函数,含有输入参数 unsigned char t,无返回值
  48. unsigned char 是定义无符号字符变量,其值的范围是
  49. 0~255 这里使用晶振12M,精确延时请使用汇编
  50. ------------------------------------------------*/
  51. void DelayMs(unsigned char t)
  52. {
  53. while(t--)
  54. {
  55. //大致延时1mS
  56. DelayUs2x(245);
  57. DelayUs2x(245);
  58. }
  59. }
  60. /*------------------------------------------------
  61. 判忙函数
  62. ------------------------------------------------*/
  63. /*
  64. bit LCD_Check_Busy(void)
  65. {
  66.         DataPort= 0xFF;
  67.         RS_CLR;
  68.         RW_SET;
  69.         EN_CLR;
  70.         _nop_();
  71.         EN_SET;
  72.         return (bit)(DataPort & 0x80);
  73. }*/
  74. /*------------------------------------------------
  75. 写入命令函数
  76. ------------------------------------------------*/
  77. void LCD_Write_Com(unsigned char com)
  78. {
  79.         //while(LCD_Check_Busy()); //忙则等待
  80.         DelayMs(5);
  81.         RS_CLR;
  82.         RW_CLR;
  83.         EN_SET;
  84.         DataPort= com;
  85.         _nop_();
  86.         EN_CLR;
  87. }
  88. /*------------------------------------------------
  89. 写入数据函数
  90. ------------------------------------------------*/
  91. void LCD_Write_Data(unsigned char Data)
  92. {
  93.         //while(LCD_Check_Busy()); //忙则等待
  94.         DelayMs(5);
  95.         RS_SET;
  96.         RW_CLR;
  97.         EN_SET;
  98.         DataPort= Data;
  99.         _nop_();
  100.         EN_CLR;
  101. }
  102. /*------------------------------------------------
  103. 清屏函数
  104. ------------------------------------------------*/
  105. /*
  106. void LCD_Clear(void)
  107. {
  108.         LCD_Write_Com(0x01);
  109.         DelayMs(5);
  110. }*/
  111. /*------------------------------------------------
  112. 写入字符串函数
  113. ------------------------------------------------*/
  114. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  115. {
  116.         if (y == 0)
  117.         {
  118.                 LCD_Write_Com(0x80 + x); //表示第一行
  119.         }
  120.         else
  121.         {
  122.                 LCD_Write_Com(0xC0 + x); //表示第二行
  123.         }
  124.         while (*s)
  125.         {
  126.                 LCD_Write_Data( *s);
  127.                 s ++;
  128.         }
  129. }
  130. /*------------------------------------------------
  131. 写入字符函数
  132. ------------------------------------------------*/
  133. /*
  134. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  135. {
  136.         if (y == 0)
  137.         {
  138.                 LCD_Write_Com(0x80 + x);
  139.         }
  140.         else
  141.         {
  142.                 LCD_Write_Com(0xC0 + x);
  143.         }
  144.         LCD_Write_Data( Data);
  145. }*/
  146. /*------------------------------------------------
  147. 初始化函数
  148. ------------------------------------------------*/
  149. void LCD_Init(void)
  150. {
  151. LCD_Write_Com(0x38); /*显示模式设置*/
  152. DelayMs(5);
  153. LCD_Write_Com(0x38);
  154. DelayMs(5);
  155. LCD_Write_Com(0x38);
  156. DelayMs(5);
  157. LCD_Write_Com(0x38);
  158. LCD_Write_Com(0x08); /*显示关闭*/
  159. LCD_Write_Com(0x01); /*显示清屏*/
  160. LCD_Write_Com(0x06); /*显示光标移动设置*/
  161. DelayMs(5);
  162. LCD_Write_Com(0x0C); /*显示开及光标设置*/
  163. }
  164. /*主程序***************************************************************/
  165. void main()
  166. {
  167.         unsigned int  Data;
  168.         inti();
  169.         while(1)
  170.         {
  171.                 Data=TH0<<8|TL0;//读计数器数据
  172.                 if(Data>=4000)
  173.                         TR0=0;
  174.                 dis_buf[0]=Data/1000%10+'0';
  175.                 dis_buf[1]=Data/100%10+'0';
  176.                 dis_buf[2]=Data/10%10+'0';
  177.                 dis_buf[3]=Data%10+'0';
  178.                 LCD_Write_String(0,0,dis_buf);

  179.         }
  180. }

复制代码



回复

使用道具 举报

地板
ID:839532 发表于 2021-5-12 11:41 | 只看该作者
aking991 发表于 2021-5-12 08:22
虽然没有附上实际运行结果图,但按个人经验来看,我认为你计算器应采用中断方式进入计数,而显示放在主函数 ...

我计数的是khz的,那我应该怎么修改啊,刚接触,写的比较简单,用的是中断计数,不知道这个计数程序写的对不对,很多东西都没想到,求大神指点一下
回复

使用道具 举报

5#
ID:839532 发表于 2021-5-12 15:14 | 只看该作者
wulin 发表于 2021-5-12 10:48
脉冲频率不太高可以用这个方式计数。你的计数和数据处理有点问题,不清楚你要显示实际数还是比例数,按需自 ...

谢谢大神谢谢谢谢,问题解决了谢谢谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表