STC8G1K08A串口搞不定,仿真搞不定,要疯了
因为有AD转换,想用串口把AD值发出来调试,用几个范例就是不行,TXD发不出数来,于是想用仿真调试,仿真也不行,出现下面的对话框.串口能下载程序,明明是好的,keil设置也是按资料设置的,怎么就不行呢,急人啊不发你程序发错误截图?这真是有才的人 拿Keil去直接仿真STC。 检查TXD端口的模式是否是可输出的,而不是高阻输入。建议用推挽输出模式 STC8H1K24的仿真我一直搞不定,是不是只要用一个USB转串口的模块连接单片机的串口和电脑,硬件连接就是这样吧?? #include "reg51.h"
#include "intrins.h"
#define FOSC 11059200UL
#define BRT (65536 - FOSC / 115200 / 4)
sfr AUXR = 0x8e;
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xc9;
sfr P5M0 = 0xca;
bit busy;
char wptr;
char rptr;
char buffer;
void UartIsr() interrupt 4
{
if (TI)
{
TI = 0;
busy = 0;
}
if (RI)
{
RI = 0;
buffer = SBUF;
wptr &= 0x0f;
}
}
void UartInit()
{
SCON = 0x50;
TMOD = 0x00;
TL1 = BRT;
TH1 = BRT >> 8;
TR1 = 1;
AUXR = 0x40;
wptr = 0x00;
rptr = 0x00;
busy = 0;
}
void UartSend(char dat)
{
while (busy);
busy = 1;
SBUF = dat;
}
void UartSendStr(char *p)
{
while (*p)
{
UartSend(*p++);
}
}
void main()
{
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
UartInit();
ES = 1;
EA = 1;
UartSendStr("Uart Test !\r\n");
while (1)
{
if (rptr != wptr)
{
UartSend(buffer);
rptr &= 0x0f;
}
}
}
就是这个范例直接拷过来,原来是P3M0=0;P3M1=0.把P3M0和P3M1改了,也不行.用它那个U8W编程器和自己的一个USB转串口都不行,能烧程序,能接收数据,就是TXD管脚发送不出来 仿真不要弄啦 串口发出的可以滴 饭桶 发表于 2022-1-20 12:31
拿Keil去直接仿真STC。
哈哈哈兄弟所言极是,仿真器用不了就不用了,直接keil软件模拟,就看出问题来了,TXD发出来了,谢谢了{:victory:} 我发现我这里就是以前用v1.13版本的仿真固件,用USB转串口接到单片机上就没问题。但是v1.14或以上的版本,就容易进不去仿真。 sandoz1cn 发表于 2022-1-20 13:03
STC8H1K24的仿真我一直搞不定,是不是只要用一个USB转串口的模块连接单片机的串口和电脑,硬件连接就是这样 ...
仿真就是这样接的,就是通过USB转串口模块连接。我这里用v1.13版本就没问题。 本帖最后由 zhuyi25762 于 2022-1-20 14:43 编辑
STC这种还要仿真??
先把串口调通,其它都好说了
我这些年用过十几个系列的单片机,STC是唯一我搞不定仿真的。汗颜! stc从来没用过仿真,都直接打印,没觉得不方便. 用最新版烧写软件,stc8h8k64u仿真刷片一次成功,用usb转ttl模块至p30 p31口 几年前用过STC15的仿真没啥问题,但对比ARM的j-link仿真感觉STC的仿真很不好用就一直没用过了 Uart1Send((AD/ 1000) + 0x30);
Uart1Send((AD / 100 % 10) + 0x30);
Uart1Send((AD / 10 % 10) + 0x30);
Uart1Send((AD % 10) + 0x30);
Uart1SendStr("\r\n");
这个很好弄的,直接发字符出来。 sayno_186 发表于 2022-1-20 23:03
Uart1Send((AD/ 1000) + 0x30);
Uart1Send((AD / 100 % 10) + 0x30);
Uart1Send((AD / 10 % 10) +...
你这样发数据,那单片机还要不要做别的事情? sayno_186 发表于 2022-1-20 23:03
Uart1Send((AD/ 1000) + 0x30);
Uart1Send((AD / 100 % 10) + 0x30);
Uart1Send((AD / 10 % 10) +...
我一样用这个方法,搞不定printf 函数就只能这样了. 我不知道怎么发附件,在高级模式里点击附件,没有输入的地方。直接贴程序。
main.c
#define MAIN_Fosc 11059200L //定义主时钟
#define UART_BaudRate1 115200UL /* 波特率 */
#include "..\..\STC8Gxxx.h"
/************* 功能说明 **************
用户请先别修改程序, 直接下载"02-5路ADC转换-BandGap-串口1(P3.1)返回结果-C语言"里的"ADC.hex"测试. 下载时选择主频11.0592MHZ。
测试时, 电脑的串口助手设置115200,8,n,1.
本程序演示4路ADC(P3.0 P3.2 P3.3 P5.4 P5.5)和bandgap查询采样,通过串口1(P3.1)发送给上位机,波特率115200,8,n,1.
0~3通道对应P3.0~P3.3, 4通道-->P5.4, 5通道-->P5.5, 15通道为内部1.19V基准电压做输入的ADC值.
初始化时先把要ADC转换的引脚设置为高阻输入.
ADC模块是一个硬件模块, 由ADC时钟驱动, 一旦触发ADC转换, 硬件会在ADC时钟驱动下自动完成.
CLK为ADC时钟, 是系统时钟的SysClk/2/(n+1)分频, ADC转换由下列操作完成:
通道选择时间 1或2个CLK (默认1)
通道选择保持时间 1~4个CLK (默认2)
模拟信号采样时间 1~32个CLK (默认11)
ADC转换时间 10个CLK(固定).
******************************************/
/************* 本地常量声明 **************/
#define ADC_START (1<<6) /* 自动清0 */
#define ADC_FLAG (1<<5) /* 软件清0 */
#define ADC_SPEED 1 /* 0~15, ADC时钟 = SYSclk/2/(n+1) */
#define RES_FMT (1<<5) /* ADC结果格式 0: 左对齐, ADC_RES: D9 D8 D7 D6 D5 D4 D3 D2, ADC_RESL: D1 D0 000000 */
/* 1: 右对齐, ADC_RES: 000000D9 D8, ADC_RESL: D7 D6 D5 D4 D3 D2 D1 D0 */
#define CSSETUP (1<<7) /* 0~1,ADC通道选择时间 0: 1个ADC时钟, 1: 2个ADC时钟,默认0(默认1个ADC时钟) */
#define CSHOLD (2<<5) /* 0~3,ADC通道选择保持时间(n+1)个ADC时钟, 默认1(默认2个ADC时钟) */
#define SMPDUTY 20 /* 10~31, ADC模拟信号采样时间(n+1)个ADC时钟, 默认10(默认11个ADC时钟) */
/* ADC转换时间: 10位ADC固定为10个ADC时钟, 12位ADC固定为12个ADC时钟. */
/************* 本地变量声明 **************/
bit B_TX1_Busy; // 发送忙标志
/************* 本地函数声明 **************/
u16 Get_ADC10bitResult(u8 channel);
void delay_ms(u8 ms);
void UART1_config(void);
void Uart1_TxByte(u8 dat);
void PrintString1(u8 *puts);
void ADC_convert(u8 chn); //chn=0~7对应P1.0~P1.7, chn=8~14对应P3.0~P3.6, chn=15对应BandGap电压
/**********************************************/
void main(void)
{
u8 i;
P3n_pure_input(0x0d); //设置要做ADC的IO做高阻输入,头文件的宏定义
P5n_pure_input(0x30); //设置要做ADC的IO做高阻输入,头文件的宏定义
ADC_CONTR = 0x80 + 0; //ADC on + channel
ADCCFG = RES_FMT + ADC_SPEED;
P_SW2 |=0x80; //访问XSFR
ADCTIM = CSSETUP + CSHOLD + SMPDUTY;
UART1_config();
EA = 1;
B_TX1_Busy= 0;
while (1)
{
ADC_convert(0);
delay_ms(200);
for(i=2; i<6; i++)
{
ADC_convert(i);
delay_ms(200);
}
ADC_convert(15); //Bandgap
delay_ms(200);
Uart1_TxByte(0x0d);
Uart1_TxByte(0x0a);
}
}
//========================================================================
// 函数: u16 Get_ADC10bitResult(u8 channel)) //channel = 0~15
// 描述: 查询法读一次ADC结果.
// 参数: channel: 选择要转换的ADC, 0~15.
// 返回: 10位ADC结果.
// 版本: V1.0, 2018-11-28
//========================================================================
u16 Get_ADC10bitResult(u8 channel) //channel = 0~15
{
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR = 0x80 | ADC_START | channel;
NOP(5); //
while((ADC_CONTR & ADC_FLAG) == 0) ; //等待ADC结束
ADC_CONTR &= ~ADC_FLAG;
#if ((RES_FMT & (1<<5)) != 0)
return ((u16)ADC_RES * 256 + (u16)ADC_RESL); //右对齐
#else
return ((u16)ADC_RES * 4 + (u16)(ADC_RESL >> 6)); //左对齐
#endif
}
#define SUM_LENGTH 16 /* 平均值采样次数 最大值16 */
/***********************************
查询方式做一次ADC, chn为通道号, chn=0~7对应P1.0~P1.7, chn=8~14对应P3.0~P3.6, chn=15对应BandGap电压.
***********************************/
void ADC_convert(u8 chn)
{
u16 j;
u8 k; //平均值滤波时使用
// Get_ADC10bitResult(chn); //参数i=0~11,15,查询方式做一次ADC, 切换通道后第一次转换结果丢弃. 避免采样电容的残存电压影响.
// Get_ADC10bitResult(chn); //参数i=0~11,15,查询方式做一次ADC, 切换通道后第二次转换结果丢弃. 避免采样电容的残存电压影响.
for(k=0, j=0; k<SUM_LENGTH; k++) j += Get_ADC10bitResult(chn); // 采样累加和 参数0~15,查询方式做一次ADC, 返回值就是结果
j = j / SUM_LENGTH; // 求平均
Uart1_TxByte('A');
Uart1_TxByte('D');
Uart1_TxByte('C');
Uart1_TxByte(chn/10+'0');
Uart1_TxByte(chn%10+'0');
Uart1_TxByte('='); //发送ADC读数
Uart1_TxByte(j/1000 + '0');
Uart1_TxByte(j%1000/100 + '0');
Uart1_TxByte(j%100/10 + '0');
Uart1_TxByte(j%10 + '0');
Uart1_TxByte(' ');
Uart1_TxByte(' ');
}
//========================================================================
// 函数: voiddelay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
voiddelay_ms(u8 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 10000;
while(--i) ;
}while(--ms);
}
//========================================================================
// 函数: void UART1_config(u8 brt)
// 描述: UART1初始化函数。
// 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void UART1_config(void) //
{
TR1 = 0;
AUXR &= ~0x01; //S1 BRT Use Timer1;
AUXR |=(1<<6); //Timer1 set as 1T mode
TMOD &= ~(1<<6); //Timer1 set As Timer
TMOD &= ~0x30; //Timer1_16bitAutoReload;
TH1 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate1) / 256;
TL1 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate1) % 256;
ET1 = 0; //禁止中断
TR1= 1;
SCON = (SCON & 0x3f) | (1<<6); // 8位数据, 1位起始位, 1位停止位, 无校验
// REN = 1; //允许接收
// PS= 1; //高优先级中断
ES= 1; //允许中断
P_SW1 = P_SW1 & 0x3f; P3n_standard(0x03); //头文件定义的宏, 切换到 P3.0 P3.1
// P_SW1 = (P_SW1 & 0x3f) | (1<<6); P3n_standard(0xc0); //头文件定义的宏, 切换到 P3.6 P3.7
// P_SW1 = (P_SW1 & 0x3f) | (2<<6); P1n_standard(0xc0); //头文件定义的宏, 切换到 P1.6 P1.7 (必须使用内部时钟)
B_TX1_Busy= 0;
}
//========================================================================
// 函数: void Uart1_TxByte(u8 dat)
// 描述: 串口1发送一个字节函数.
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void Uart1_TxByte(u8 dat)
{
B_TX1_Busy = 1; //标志发送忙
SBUF = dat; //发一个字节
while(B_TX1_Busy); //等待发送完成
}
//========================================================================
// 函数: void UART1_int (void) interrupt UART1_VECTOR
// 描述: 串口1中断函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void UART1_int (void) interrupt UART1_VECTOR
{
if(RI)
{
RI = 0;
}
if(TI)
{
TI = 0;
B_TX1_Busy = 0;
}
}
STC8Gxxx.h
内容太长贴不了 楼主可以将邮箱通过短信发给STC技术支持13922829991索要上面的程序。 lzy888 发表于 2022-1-20 13:15
#include "reg51.h"
#include "intrins.h"
你这个占用了仿真口了,串口1要映射到其它口去 jswd2420 发表于 2022-1-21 14:50
你这个占用了仿真口了,串口1要映射到其它口去
并不是的,把串口1部分全部删掉,只保留点灯代码,依然提示这样的错误 本帖最后由 lzy888 于 2022-1-21 15:35 编辑
小李非刀 发表于 2022-1-21 14:07
我不知道怎么发附件,在高级模式里点击附件,没有输入的地方。直接贴程序。
main.c
#define MAIN_Fosc 110 ...
谢谢,AD搞定了,串口也搞定了,就是仿真还没有搞定,仿真倒不是必须的. lzy888 发表于 2022-1-21 15:32
并不是的,把串口1部分全部删掉,只保留点灯代码,依然提示这样的错误
你STC-ISP仿真设置里面点了“将所选目标单片机设置为仿真芯片”了? jswd2420 发表于 2022-1-21 15:39
你STC-ISP仿真设置里面点了“将所选目标单片机设置为仿真芯片”了?
怕一次设置仿真不行,每次烧完代码就设置仿真一次,设置仿真就像烧代码的过程一样.设置完了然后在keil编译程序后点那个红色调试代码,就出现一楼的错误提示
lzy888 发表于 2022-1-21 15:44
怕一次设置仿真不行,每次烧完代码就设置仿真一次,设置仿真就像烧代码的过程一样.设置完了然后在keil编译 ...
我用stc8仿真一般遇见这种问题有几种可能:1、板子电源没有上;2、通讯口不对;3、编译时的通讯口不是实际用的通讯口;4、设置完仿真后最好断下电 jswd2420 发表于 2022-1-21 15:53
我用stc8仿真一般遇见这种问题有几种可能:1、板子电源没有上;2、通讯口不对;3、编译时的通讯口不是实 ...
你说的这几个问题应当都不存在,因为烧代码唰唰的挺顺利.是不是这个型号的都有这个问题呢,这就不清楚了 redworlf007 发表于 2022-1-21 22:46
说个单片机届的笑话:Stc仿真
某宝有STC-LINK,很便宜。可以买来试试看。 王二小 发表于 2022-1-21 22:58
某宝有STC-LINK,很便宜。可以买来试试看。
我的回复被屏蔽了…… 王二小 发表于 2022-1-21 22:58
某宝有STC-LINK,很便宜。可以买来试试看。
{:lol:} 你说的STC-LINK拆开里面就是一个串口模块吧,换个名字好听点? C指针 发表于 2022-1-22 18:31
你说的STC-LINK拆开里面就是一个串口模块吧,换个名字好听点?
我平时是用ch340下载没遇到过问题。
我没用过STC-LINK,25块钱1个。这是商家宣传文案。
另外可以单独购买STC-LINK芯片。坐等大佬买个STC-LINK做下测评。
这个RAM很小就不要仿真了,51很少有人用仿真,把STC的串口例程抄一下,然后在调外设,串口打印 STC还需要仿真呀,也许是我没写过大程序吧 仿真找问题很快的
没有仿真我都不习惯了
页:
[1]