论坛风格切换切换到宽版
  • 4274阅读
  • 38回复

STC15F104W的怪事 [复制链接]

上一主题 下一主题
离线BD7IRK
发帖
178
只看该作者 20楼 发表于: 2020-01-20
我觉得你可以检查下你内部振荡器的频率设置跟程序头部备注的频率是否一致。

内容来自Android手机客户端

离线BG4UVR
发帖
11201
只看该作者 21楼 发表于: 2020-01-21
把这一部分的完整代码贴上来看看呢,感觉不应该这么离奇啊,这不科学啊
离线BG1TRP
发帖
18096
只看该作者 22楼 发表于: 2020-01-21
uchar code *ROM_Addr;

INT_CLKO = 0;
CLK_DIV = 0;
P3M0 = 0x00;
P3M1 = 0x00;

ROM_Addr = 0x0FF9;

for(i = 0; i < 7; i++)
{
    PlayCharacter(HEXtoASCII(*ROM_Addr >> 4));
    PlayCharacter(HEXtoASCII(*ROM_Addr & 0xF));
        _nop()_;
    ROM_Addr++;
}

uchar HEXtoASCII(uchar Date)
{
    Date &= 0x0F;
    if(Date <= 9)
    {
        return (Date + '0');
    }
    else
    {
        return (Date - 10 + 'A');
    }
}
都是STC的代码
HEXtoASCII()是16进制数转ASCII码
真没啥难的,就是太怪了,烧录软件上能显示出全部14个ID码,用这个代码只能显示8个ID码。
用示波器看了看,检查了主时钟,没问题,定时器T0工作正常。

前面还有个数组定义在CODE区,这个会影响到ROM_addr?
const uchar code A[7][2] = {0xFB,0xFB,0xFC,0xFC,0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFE,0xFE};

芯片的硬件版本7.2.5Q
[ 此帖被BG1TRP在2020-01-21 11:43重新编辑 ]
英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件
离线BG4FQD
发帖
3405
只看该作者 23楼 发表于: 2020-01-21
你这个PlayCharacter 是个啥?LCD上显示字母的?
你首先需要排查一下是显示不出来还是读不出来。
别人吃饭我看着,别人睡觉我站着。
离线BG1TRP
发帖
18096
只看该作者 24楼 发表于: 2020-01-21
回 BG4FQD 的帖子
BG4FQD:你这个PlayCharacter 是个啥?LCD上显示字母的?
你首先需要排查一下是显示不出来还是读不出来。
 (2020-01-21 12:37) 

PlayCharacter就是输出字母的,与读取ROM无关。
您这一提醒找到病根了,在PlayChaater里面用到循环变量 i,以前是在模块里单独定义的,现在用的是全局变量i,这样读ROM和输出字符都用到同一个i,导致循环变量错误,因此就乱了套了。在PlayCharter里单独定义i后,读了7次就得到ID了。谢谢。

现在就是RAM读出来全是零,网上也有个帖子提到读出的全是零,手册里也提到RAM区ID易受攻击,是不是STC放弃了RAM区ID?

非常感谢各位关心这个帖子的各位朋友。
英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件
离线BG1TRP
发帖
18096
只看该作者 25楼 发表于: 2020-01-21
http://www.51hei.com/bbs/dpj-39827-1.html
这是说读RAM全为0的帖子
英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件
离线BG4UVR
发帖
11201
只看该作者 26楼 发表于: 2020-01-21
一般来讲,单片机的制造企业,不太会范低级错误,这种明显的问题,我的观点还是主要从自身找问题。把读ram的代码上来看看^_^
离线BG4UVR
发帖
11201
只看该作者 27楼 发表于: 2020-01-21
犯,手机,错字……
离线BG1TRP
发帖
18096
只看该作者 28楼 发表于: 2020-01-21
使用全局变量i做循环,纯属手欠。由于内存空间只有128,想省着用,结果改出毛病来了。
您说的没错,多次遇到怪事儿,最后查出来还是自己代码的毛病,最头痛那种没有编译错误的问题。

uchar idata *RAM_Addr = 0x71;
for(i = 0; i < 7; i++)
{
    Array{i} = *RAM_Addr;
    RAM_Addr++;
}
运行后Array里不是ID码,不知道是啥玩意。
也是STC的代码。
STC15F104W只有128bit内存空间,没有扩展空间。地址0x71应该在范围内。


[ 此帖被BG1TRP在2020-01-21 22:27重新编辑 ]
英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件
离线BG1TRP
发帖
18096
只看该作者 29楼 发表于: 2020-01-23
不知是不是指令的运行速度比STC12快的问题,有些与时序有关的代码STC12上正常运行的,直接移植过来就不行。用示波器看了一下,端口电平切换的状态没问题,就是的不到所需的结果。
主频降低也不行,也许与主频无关。
英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件
离线BG1TRP
发帖
18096
只看该作者 30楼 发表于: 2020-01-24
这个芯片的指针变量好像挺脆弱,容易遭到破坏:
uchar *ROM_id = 0xFF9;
...
...
for (i = 1; i < 7; i++)
  id = *ROM_id++;

这样有的时候读不出来,定义指针变量到使用指针变量之间没有涉及*ROM_id的操作,没有使用全局变量,有其他指针变量的操作(读写EEPROM),改成下面这样还没出现读不出来的状况。

uchar *ROM_id;
...
...
ROM_id = 0xFF9;
for (i = 1; i < 7; i++)
  id = *ROM_id++;


英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件
离线BG4UVR
发帖
11201
只看该作者 31楼 发表于: 2020-01-29
你的程序使用RAM比较多么?会不会是堆栈溢出了?
离线BG4UVR
发帖
11201
只看该作者 32楼 发表于: 2020-01-29
直接用官方的代码试试呢?(代码我没仔细检查,也许会有复制造成的排版错误)

  1. /*-----------------------------------------------------------------*/
  2. /* --- STC MCU Limited --------------------------------------------*/
  3. /*STC15F104W 系列 读取程序区 ID 号并用软件模拟串口输出显示举例------*/
  4. /* --- Mobile: (86)13922805190 ------------------------------------*/
  5. /* --- Fax: 86-755-82905966 ---------------------------------------*/
  6. /* --- Tel: 86-755-82948412 ---------------------------------------*/
  7. /* --- Web: www.STCMCU.com ----------------------------------------*/
  8. /*如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序*/
  9. /*如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序*/
  10. /*-----------------------------------------------------------------*/
  11. //本示例在 Keil 开发环境下请选择 Intel 的 8058 芯片型号进行编译
  12. //假定测试芯片的工作频率为 18.432MHz
  13. #include "reg51.h"
  14. //-----------------------------------------
  15. //define baudrate const
  16. //BAUD=256 - FOSC/3/BAUDRATE/M (1T:M=1; 12T:M=12)
  17. //NOTE: (FOSC/3/BAUDRATE) must be greater then 98, (RECOMMEND GREATER THEN 110)
  18. //#define BAUD 0xF400 // 1200bps @ 11.0592MHz
  19. //#define BAUD 0xFA00 // 2400bps @ 11.0592MHz
  20. //#define BAUD 0xFD00 // 4800bps @ 11.0592MHz
  21. //#define BAUD 0xFE80 // 9600bps @ 11.0592MHz
  22. //#define BAUD 0xFF40 //19200bps @ 11.0592MHz
  23. //#define BAUD 0xFFA0 //38400bps @ 11.0592MHz
  24. //#define BAUD 0xEC00 // 1200bps @ 18.432MHz
  25. //#define BAUD 0xF600 // 2400bps @ 18.432MHz
  26. //#define BAUD 0xFB00 // 4800bps @ 18.432MHz
  27. //#define BAUD 0xFD80 // 9600bps @ 18.432MHz
  28. //#define BAUD 0xFEC0 //19200bps @ 18.432MHz
  29. #define BAUD 0xFF60 //38400bps @ 18.432MHz
  30. //#define BAUD 0xE800 // 1200bps @ 22.1184MHz
  31. //#define BAUD 0xF400 // 2400bps @ 22.1184MHz
  32. //#define BAUD 0xFA00 // 4800bps @ 22.1184MHz
  33. //#define BAUD 0xFD00 // 9600bps @ 22.1184MHz
  34. //#define BAUD 0xFE80 //19200bps @ 22.1184MHz
  35. //#define BAUD 0xFF40 //38400bps @ 22.1184MHz
  36. //#define BAUD 0xFF80 //57600bps @ 22.1184MHz
  37. #define ID_ADDR_RAM 0x71 //STC104W系列ID号的存放在RAM区的地址
  38. #define ID_ADDR_ROM 0x0ff9 //STC104W系列ID号的存放在ROM区的地址
  39. sfr AUXR=0x8E;
  40. sbit RXB=P3^0; //定义串口 TX/RX 引脚
  41. sbit TXB=P3^1;
  42. typedef bit BOOL;
  43. typedef unsigned char BYTE;
  44. typedef unsigned int WORD;
  45. BYTE TBUF,RBUF;
  46. BYTE TDAT,RDAT;
  47. BYTE TCNT,RCNT;
  48. BYTE TBIT,RBIT;
  49. BOOL TING,RING;
  50. BOOL TEND,REND;
  51. void UART_INIT();
  52. void UART_SEND(BYTE dat);
  53. BYTE t, r;
  54. BYTE buf[16];
  55. void main()
  56. {
  57.     BYTE idata* iptr;
  58.     BYTE code* cptr;
  59.     BYTE i;
  60.     TMOD=0x00; //定时器 0 在 16 位自动重装模式
  61.     AUXR=0x80; //定时器 0 在 1T 模式
  62.     TL0=BAUD;
  63.     TH0=BAUD>>8; //初始化定时器 0 并设定重装值
  64.     TR0=1; //定时器 0 开始运行
  65.     ET0=1; //使能定时器 0 中断
  66.     PT0=1; //improve timer0 interrupt priority
  67.     EA=1; //打开中断开关
  68.     UART_INIT();
  69.     iptr=ID_ADDR_RAM; //从 RAM 区读取 ID 号
  70.     for(i=0; i<7; i++)  //读 7 个字节
  71.     {
  72.         UART_SEND(*iptr++); //发送 ID 到串口
  73.     }
  74.     cptr=ID_ADDR_ROM; //从程序区读取 ID 号
  75.     for(i=0; i<7; i++)  //读 7 个字节
  76.     {
  77.         UART_SEND(*cptr++); //发送 ID 到串口
  78.     }
  79.     while(1);  //程序终止
  80. }
  81. //-----------------------------------------
  82. //Timer interrupt routine for UART
  83. void tm0() interrupt 1 using 1
  84. {
  85.     if(RING)
  86.     {
  87.         if(--RCNT == 0)
  88.         {
  89.             RCNT=3; //reset send baudrate counter
  90.             if(--RBIT == 0)
  91.             {
  92.                 RBUF=RDAT; //保存数据到 RBUF
  93.                 RING=0; //停止接收
  94.                 REND=1; //设置接收完成标志
  95.             }
  96.             else
  97.             {
  98.                 RDAT >>= 1;
  99.                 if(RXB) RDAT |= 0x80;  //移位 RX 数据到 RX 缓冲
  100.             }
  101.         }
  102.     }
  103.     else if(!RXB)
  104.     {
  105.         RING=1; //设置开始接收标志
  106.         RCNT=4; //initial receive baudrate counter
  107.         RBIT=9; //初始化接收位数(8 数据位+1 停止位)
  108.     }
  109.     if(--TCNT == 0)
  110.     {
  111.         TCNT=3; //reset send baudrate counter
  112.         if(TING)  //judge whether sending
  113.         {
  114.             if(TBIT == 0)
  115.             {
  116.                 TXB=0; //发送开始位
  117.                 TDAT=TBUF; //从 TBUF 加载数据到 TDAT
  118.                 TBIT=9; //初始化发送位数(8 数据位+1 停止位)
  119.             }
  120.             else
  121.             {
  122.                 TDAT >>= 1; //移位数据到 CY
  123.                 if(--TBIT == 0)
  124.                 {
  125.                     TXB=1;
  126.                     TING=0; //停止发送
  127.                     TEND=1; //设置发送完成标志
  128.                 }
  129.                 else
  130.                 {
  131.                     TXB=CY; //写 CY 到 TX 脚
  132.                 }
  133.             }
  134.         }
  135.     }
  136. }
  137. //-----------------------------------------
  138. //initial UART module variable
  139. void UART_INIT()
  140. {
  141.     TING=0;
  142.     RING=0;
  143.     TEND=1;
  144.     REND=0;
  145.     TCNT=0;
  146.     RCNT=0;
  147. }
  148. //-----------------------------------------
  149. //发送串口数据
  150. void UART_SEND(BYTE dat)
  151. {
  152.     while(!TEND);
  153.     TEND=0;
  154.     TBUF=dat;
  155.     TING=1;
  156. }





[ 此帖被BG4UVR在2020-01-29 14:49重新编辑 ]
离线BG4UVR
发帖
11201
只看该作者 33楼 发表于: 2020-01-29
对了,如果是用KEIL编译的,那么如果你的项目加载了默认的STARTUP.A51,那么这段代码会默认清零所有RAM的
离线BG1TRP
发帖
18096
只看该作者 34楼 发表于: 2020-01-29
回 BG4UVR 的帖子
BG4UVR:对了,如果是用KEIL编译的,那么如果你的项目加载了默认的STARTUP.A51,那么这段代码会默认清零所有RAM的[表情]  (2020-01-29 15:42) 

读ID的代码就是用的STC的,只不过他读出来后通过串口发送了,我是直接把ID显示出来。

看了一下.A51文件,注解只是说IDATA与DATA重叠,范围是0X0-0X100, 起始地址永远是0。

编译用的是KEIL,12系列芯片就没有这个问题。这个芯片与12系列在内存上的区别只是没有XDATA。
英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件
离线BG4UVR
发帖
11201
只看该作者 35楼 发表于: 2020-01-30
上午回复时,神聊的证书过期了,重新登录时没注意,竟然是用马甲号回复的
离线BG1TRP
发帖
18096
只看该作者 36楼 发表于: 2020-01-31
回 BG4UVR 的帖子
BG4UVR:上午回复时,神聊的证书过期了,重新登录时没注意,竟然是用马甲号回复的[表情] (2020-01-30 14:06)

可以把那个回复删掉,或者找CK索赔
我先把回复删了。

[ 此帖被BG1TRP在2020-01-31 11:11重新编辑 ]
英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件
离线BG4UVR
发帖
11201
只看该作者 37楼 发表于: 2020-01-31
回 BG1TRP 的帖子
BG1TRP:可以把那个回复删掉,或者找CK索赔[表情]
我先把回复删了。
 (2020-01-31 11:10) 

没关系,我那马甲不干坏事
而且,我那马甲的特点是,比大号注册时间还早
离线BG1TRP
发帖
18096
只看该作者 38楼 发表于: 2020-01-31
不知道CK的马甲是哪个

调试中发现这个芯片搭配MCP4011数字使用,不能完全按照MCP4011的时序编程,高电位的延时要适当加长,不知是否与速度快有关。
英文版CW工具箱 TRP-BOX V6 (新版):https://www.hellocq.net/forum/read.php?tid=365349
三合一台咪套件
天线切换器套件