找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1939|回复: 18
收起左侧

STC8H1K28单片机按键程序移植问题 按键就不能控制端口输出高低电平

[复制链接]
ID:1001745 发表于 2022-12-6 17:35 | 显示全部楼层 |阅读模式
如下程序,在STC8H1K17 -TSSOP-20上运行正常,移植到STC8H1K28-LQFP-28上任何按键就不能控制端口输出高低电平了。根据端口设置我也重新定义和配置了。查了规格书也没有查出来什么问题,特此请教各位大师!望不吝赐教。

单片机源程序如下:
#include "STC8H.H"
#include "intrins.h"

typedef unsigned char   u8;
typedef unsigned int    u16;
bit flag_400ms=1,flag_1s=1,flag_5s=1;
bit flag_1ms = 0;                         //1ms标志位
u16 press_delay = 0;        //按下计数器标志位
u16 release_delay = 0;      //放开计数器标志位
u8 key_val = 0;                                 //增加按键标志位
u8 click_count = 0;                        //增加按键次数

sbit SW=P2^0;
sbit sta=P2^7;
sbit ledr=P3^0;

void Timer0()interrupt 1
{
TH0 = 0xfc;         //给定时器赋初始值为1ms
TL0 = 0x18;         
flag_1ms = 1;       //1ms标志位
}

void key_pos()
{
if(flag_1ms==1)
{
  flag_1ms = 0;
  if(SW==0)           //判断模式按键是否按下
  {
   if(press_delay<0xffff)press_delay++;
   if(press_delay==20)                 //20ms消抖处理
   {
    click_count++;
   }
   if(press_delay==3000)
   {
    key_val = 10;
   }
   release_delay = 0;
  }
  else
  {
   if(release_delay<0xff)release_delay++;
   if(release_delay==200)
   if(press_delay<3000)
   {
    key_val = click_count;
        click_count = 0;
   }
   press_delay = 0;
  }
  if(key_val > 0)         //若有按键按下
  {
   if(key_val==10)         //长按1.5s
   {
    ledr = ~ledr;      //控制端状态取反
        
        click_count = 0;
   }
   else if(key_val==1)
   {
    sta = ~sta;     //控制端状态取反
        
   }
   else if(key_val==2)
   {
    ledr = ~ledr;    //控制端口状态取反
    sta = ~sta;
        
   }

   key_val = 0;
  }
}
}

void main()
{

    P0M1 = 0x0d;        //修改P00端口高阻改为推挽
    P0M0 = 0x00;        //修改p00端口高阻模式改为推挽模式   
    P1M1 = 0xc0;
    P1M0 = 0x3F;
    P2M1 = 0x00;        
    P2M0 = 0xb8;                           //修改P27;P20端口为推挽输出
    P3M1 = 0x88;
    P3M0 = 0x02;
        sta = 1;
        ledr=0;
         
while(1)
{
         void key_pos();
}
}


回复

使用道具 举报

ID:1034262 发表于 2022-12-6 21:58 | 显示全部楼层
while(1)
{
         void key_pos();
}

这样写编译能通过吗?
回复

使用道具 举报

ID:1001745 发表于 2022-12-7 08:03 | 显示全部楼层
coody_sz 发表于 2022-12-6 21:58
while(1)
{
         void key_pos();

只是有警告但是还是能通过的。
回复

使用道具 举报

ID:1001745 发表于 2022-12-7 08:08 | 显示全部楼层
这是编译的结果
by.png
回复

使用道具 举报

ID:308903 发表于 2022-12-7 08:21 | 显示全部楼层
我怀疑没配置好, 你贴出电路图,比较相对应的IO管脚上,功能是否一样? 毕竟一个20PIN ,一个28PIN
回复

使用道具 举报

ID:814525 发表于 2022-12-7 08:52 | 显示全部楼层
P2M0 = 0xb8;     //修改P27;P20端口为推挽输出
把SW--P2.0改为弱上拉准双向口!!!
回复

使用道具 举报

ID:1001745 发表于 2022-12-7 08:53 | 显示全部楼层
图片为两个MCU的引脚配置电路图
STC8H1K17.png
STC8H1K28.png
回复

使用道具 举报

ID:624769 发表于 2022-12-7 08:59 来自手机 | 显示全部楼层
mcuhui 发表于 2022-12-7 08:08
这是编译的结果

你理解一下这个警告的意思,想一想,出了这个警告之后,编译通过没通过,有区别么?
回复

使用道具 举报

ID:1001745 发表于 2022-12-7 09:04 | 显示全部楼层
张天师 发表于 2022-12-7 08:52
P2M0 = 0xb8;     //修改P27;P20端口为推挽输出
把SW--P2.0改为弱上拉准双向口!!!

大师,改过试过呢,P2M0 = 0xb8;这就是P2.0口配置为双向IO口
回复

使用道具 举报

ID:1001745 发表于 2022-12-7 09:08 | 显示全部楼层
188610329 发表于 2022-12-7 08:59
你理解一下这个警告的意思,想一想,出了这个警告之后,编译通过没通过,有区别么?

还请大师赐教,就是菜鸟一个不懂啊。看着HEX文件是有生成的。所以不知道为何会有这个警告,也不知这个警告该如何解决?
回复

使用道具 举报

ID:213173 发表于 2022-12-7 10:54 | 显示全部楼层
mcuhui 发表于 2022-12-7 09:08
还请大师赐教,就是菜鸟一个不懂啊。看着HEX文件是有生成的。所以不知道为何会有这个警告,也不知这个警 ...

沙发已经指出错误,而且这个错误会导致按键程序不能正常运行。去掉void关键词试试。
while(1)
{
         key_pos();
}
楼主这段原代码写的实在有点......
回复

使用道具 举报

ID:1001745 发表于 2022-12-7 11:04 | 显示全部楼层
wulin 发表于 2022-12-7 10:54
沙发已经指出错误,而且这个错误会导致按键程序不能正常运行。去掉void关键词试试。
while(1)
{

我也发现了这个问题,把void去掉就不会有编译警告。但是还是不能控制高低电平输出。知道自己几斤几两的水平,但是没办法就这点能力,大师见笑啦
回复

使用道具 举报

ID:213173 发表于 2022-12-7 14:22 | 显示全部楼层
mcuhui 发表于 2022-12-7 11:04
我也发现了这个问题,把void去掉就不会有编译警告。但是还是不能控制高低电平输出。知道自己几斤几两的水 ...

给你写一个适合STC8系列的长短按程序示例,基本通用于STC所有1T单片机。
  1. #include "STC8H.H"
  2. #include "intrins.h"

  3. #define key_S 15                                //宏定义短按(约15ms)
  4. #define key_L key_S*67                        //宏定义长按(约1s)

  5. sbit SW=P2^0;
  6. sbit sta=P2^7;
  7. sbit ledr=P3^0;

  8. //定时器初始化程序
  9. void Timer0Init(void)                //1毫秒@11.0592MHz
  10. {
  11.         AUXR |= 0x80;                //定时器时钟1T模式
  12.         TMOD &= 0xF0;                //设置定时器模式
  13.         TL0 = 0xCD;                //设置定时初始值
  14.         TH0 = 0xD4;                //设置定时初始值
  15.         TF0 = 0;                //清除TF0标志
  16.         TR0 = 1;                //定时器0开始计时
  17. }


  18. void keyscan()
  19. {
  20.         static unsigned int time=0;//计数变量

  21.         if(!SW)//按键按下
  22.         {
  23.                 time++;
  24.                 if(time>key_L)
  25.                 {
  26.                         time=key_L+1;//防止time溢出
  27.                 }
  28.                 if(time==key_L)//长按
  29.                 {
  30.                         ledr = ~ledr;//长按任务
  31.                 }
  32.         }
  33.         else                                //松手
  34.         {
  35.                 if(time>key_S && time<key_L)//短按
  36.                 {
  37.                         sta = ~sta;//短按任务
  38.                 }
  39.                 time=0;
  40.         }
  41. }

  42. void main()//主函数
  43. {
  44. //所有端口初始化为准双向口
  45.         P0M0 = 0x00;
  46.         P0M1 = 0x00;
  47.         P1M0 = 0x00;
  48.         P1M1 = 0x00;
  49.         P2M0 = 0x00;
  50.         P2M1 = 0x00;
  51.         P3M0 = 0x00;
  52.         P3M1 = 0x00;
  53.         P4M0 = 0x00;
  54.         P4M1 = 0x00;
  55.         P5M0 = 0x00;
  56.         P5M1 = 0x00;
  57.         P6M0 = 0x00;
  58.         P6M1 = 0x00;
  59.         P7M0 = 0x00;
  60.         P7M1 = 0x00;
  61.         sta = 1;
  62.         ledr=0;
  63.         Timer0Init();//初始化定时器
  64.         while(1)
  65.         {
  66.                 if(TF0)//查询定时器中断请求位
  67.                 {
  68.                         TF0=0;//清0
  69.                         keyscan();                //按键扫描函数
  70.                 }
  71.         }
  72. }
复制代码
回复

使用道具 举报

ID:123289 发表于 2022-12-7 15:31 | 显示全部楼层
再读一读IO的手册部分。对照一下,程序是如何处理IO口的。
回复

使用道具 举报

ID:401564 发表于 2022-12-7 17:10 | 显示全部楼层
我经常犯这种错误:一段代码运行多次之后,只要结果是符合我的要求了,我就认为我这段代码没有问题了
但是,当我把这段代码用到别的地方了,才发现:我之前的代码根本是错误的,能正常运行可能是误打误撞的
你这代码本就不多,自己用排除法就行
1:把按键什么的代码都不要了,只要几行代码,端口初始化,再把一个端口拉高,烧录看一下,问题就能找到了
如果端口没有高电平,那么,不是端口配置不正确就是硬件的问题
如果端口一切正常,那就去检查一下按键部分的代码
回复

使用道具 举报

ID:1001745 发表于 2022-12-8 08:20 | 显示全部楼层
yzwzfyz 发表于 2022-12-7 15:31
再读一读IO的手册部分。对照一下,程序是如何处理IO口的。

嗯,还是怪自己学艺不精,太菜了。还没有搞懂这其中的原理,后来我又仔细的看了一遍原先的STC8H1K17的代码已经规格书,发现既然把定时函数忘记了。谢谢解答!
回复

使用道具 举报

ID:1001745 发表于 2022-12-8 08:21 | 显示全部楼层
Y_G_G 发表于 2022-12-7 17:10
我经常犯这种错误:一段代码运行多次之后,只要结果是符合我的要求了,我就认为我这段代码没有问题了
但是,当 ...

是的,后来我就尝试着在其它端口去测试看看代码能不能正常允许然后再去找问题点,结果发现是忘记加定时函数了。谢谢解答!
回复

使用道具 举报

ID:123289 发表于 2022-12-8 08:55 | 显示全部楼层
你不菜,只是未找到学习的方法。
学单片机,最重要的是读通CPU手册。
你想啊,你要做A,如果对A不了解,如果做得精,做得好。
记住永远的法则:要控制什么,就必须先了解什么!!!
所以,只有读通手册,才能精通单片机!!
当你了解了CPU之后,写程序的目的,措施就明确了,对他人的经典的程序也就能理解了,写程序也就不难了。
劝君,花个把月,读通CPU。不会的可以与我讨论。我就喜欢读各式各样的器件手册。只要是PCB板上有的东东,手册都找来读。
回复

使用道具 举报

ID:1001745 发表于 2022-12-8 10:14 | 显示全部楼层
yzwzfyz 发表于 2022-12-8 08:55
你不菜,只是未找到学习的方法。
学单片机,最重要的是读通CPU手册。
你想啊,你要做A,如果对A不了解, ...

感谢大师的鼓励,一定会好好看规格书并学以致用!谢谢!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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