STC8G1KO8A取代STC15W104中遇到的问题
本帖最后由 ecoo 于 2023-2-22 11:34 编辑最近在移植一段开源的电调程序到stc8G1K08A,根据手册指引;
改了include,增加了STC8G.h和intrins.h
改了IO配置;
增加了eeprom的iap_tps指令;
复位脚用作IO输出,未改动;
初始化中配置了引脚准双向;
根据例程的eeprom基础操作改了程序的eeprom操作。
编译过程未报错,实际下载程序后,能看到初始化的输出波形,但是主程序没反应,请大佬指正下程序哪里没改到位。
#include<STC8G.h>
#include<intrins.h>
#define u8 unsigned char
#define u16 unsigned int
sbit IN=P5^4; //修改引脚定义
//sbit Mode_IN=P5^5; //模式引脚
sbit A1=P3^3;
sbit A2=P3^2;
sbit B1=P3^1;
sbit B2=P3^0;
bit turn;
bit stop,go;
bit ok,lose,error;
bit mode;
u8 MARK1,MARK2,low,top,calabration,over,n;
u8 step;
u16 time,tt ;
u16 MAX,MINE,MIDDLE,k; //修改冲突的min>>mine
u16 Timer2_value;
u16 phase_time;
int speed;
void Delay100us() //@12.000MHz,修改为Y6指令集
{
unsigned char i, j;
_nop_();
i = 2;
j = 140;
do
{
while (--j);
} while (--i);
}
void delay(u16 t)
{
while(t--)
Delay100us();
}
u8 EEPROM_read(u8 address)
{
char byte;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = address; //设置IAP低地址
IAP_ADDRH = address >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
byte = IAP_DATA; //读IAP数据
IAP_CONTR = 0; //关闭IAP功能
return byte;
}
void EEPROM_write(u8 address,u8 byte)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = address; //设置IAP低地址
IAP_ADDRH = address >> 8; //设置IAP高地址
IAP_DATA = byte; //写IAP数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IAP_CONTR = 0;
// IAP_CONTR=0x80; //以下为源程序eeprom操作
//IAP_ADDRL=address;
//IAP_DATA=byte;
//IAP_CMD=0x02;
//IAP_TRIG=0x46;
//IAP_TRIG=0xb9;
}
void EEPROM_clean(u8 address)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = address; //设置IAP低地址
IAP_ADDRH = address >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IAP_CONTR = 0; //关闭IAP功能
// IAP_CONTR=0x80; //源程序eeprom操作
//IAP_ADDRL=address;
//IAP_CMD=0x03;
//IAP_TRIG=0x46;
//IAP_TRIG=0xb9;
}
void DATA_read()
{
IAP_CONTR=0x83; //修改
IAP_TPS = 12; //设置等待参数12MHz
MARK1=EEPROM_read(0);
MARK2=EEPROM_read(1);
MAX=EEPROM_read(2);
MAX<<=8;
MAX+=EEPROM_read(3);
MIDDLE=EEPROM_read(4);
MIDDLE<<=8;
MIDDLE+=EEPROM_read(5);
IAP_CONTR=0;
}
void DATA_save()
{
IAP_CONTR=0x83; //修改
IAP_TPS = 12; //设置等待参数12MHz
EEPROM_clean(0);
EEPROM_write(0,0x0f);
EEPROM_write(1,0xa5);
EEPROM_write(2,MAX>>8);
EEPROM_write(3,MAX);
EEPROM_write(4,MIDDLE>>8);
EEPROM_write(5,MIDDLE);
IAP_CONTR=0;
}
void measure()
{
time=0;
TL0=0,TH0=0;
while(!IN);
TR0=1;
while(IN);
TR0=0;
time=TH0;
time<<=8;
time+=TL0;
}
void shock(u8 n) //beep
{
u8 i;
for(i=0;i<250;i++)
{
A1=1;A2=0;
delay(n);
A1=0;A2=1;
delay(n);
}
A1=0;A2=0;
}
void initial()
{
u8 i;
P3M1=0x00; //修改准双向
P3M0=0x00;
P5M1=0x00;
P5M0=0x00;
TMOD=0x01;
A1=0;
A2=0;
B1=0;
B2=0;
delay(2000);
shock(2); //上电能观察到输出
shock(3);
shock(4);
delay(5000);
// mode=Mode_IN;
mode=1; //1为2相,0取四相
measure();
measure();
measure();
measure();
measure();
DATA_read();
if(MARK1!=0x0f||MARK2!=0xa5) //16bit,if((MARK1==0x0f)&&(MARK2==0xa5))
{
MAX=1950;MIDDLE=1500; //默认标准行程
}
over=1;
while(over)
{
measure();
if(time>1700) //上电油门高位校准行程
{
i++;
if(i>100)over=0,calabration=1; //校准
}
else
{
if(time<MIDDLE+50&&time>MIDDLE-50) //校准完成
{
over=0;
shock(4);
shock(3);
shock(2);
}
}
}
if(MAX>2200||MIDDLE<1300)
{
calabration=1;
if(MAX<1700||MIDDLE>1700)calabration=1;
}
if(calabration)
{
over=1;
while(over)
{
measure();
if(time>1700)over=0;
}
delay(5000);delay(5000);
shock(4);
delay(2000);
shock(4);
measure();
measure();
if(time>1700&&time<2200)MAX=time;
else error=1;
over=1;
while(over)
{
measure();
if(time<1700&&time>1300)over=0;
}
delay(5000);delay(5000);
shock(4);
delay(2000);
shock(4);
measure();
measure();
if(time>1300&&time<1700)MIDDLE=time;
else error=1;
if(error==0)DATA_save();
delay(2000);
shock(4);
shock(3);
shock(2);
}
}
main()
{
initial();
stop=1;
IE=0x80; //中断
IE2=0x04;
MINE=MIDDLE+MIDDLE-MAX;
k=MAX-MIDDLE;
AUXR=0x10; //开定时器2
while(1) //正常工作
{
measure();
// shock(2); //测试主程序循环用方波
if(lose) //失控待机
{
delay(1000);
measure();
measure();
}
if(time>800&&time<2200) //主程序
{
ok=1;lose=0;
if(time>MIDDLE+50)
{
stop=0,go=1;
if(time>MAX)time=MAX;
speed=(long)(time-MIDDLE )*100/k;
phase_time=11000-speed*100; //11ms~1ms换向时间调节,最大0.4ms,取值范围10400~11000(根据电机)
Timer2_value=65535-phase_time;
}
else if(time<MIDDLE-50)
{
stop=0,go=0;
if(time<MINE)time=MINE;
speed=(long)(MIDDLE- time)*100/k;
phase_time=11000-speed*100;
Timer2_value=65535-phase_time;
}
else
{
stop=1;
}
}
}
}
void et2()interrupt 12 //定时驱动
{
if(stop) //停止
{
T2L=0x18,T2H=0xfc; //1ms
A1=0,A2=0,B1=0,B2=0;
}
else //转动
{
T2L=Timer2_value,T2H=Timer2_value>>8; //11ms~1ms换向时间调节
if(mode) //两相 8拍,MODE=1
{
if(step==0)A1=1,A2=0,B1=0,B2=0;
else if(step==1)A1=1,A2=0,B1=1,B2=0;
else if(step==2)A1=0,A2=0,B1=1,B2=0;
else if(step==3)A1=0,A2=1,B1=1,B2=0;
else if(step==4)A1=0,A2=1,B1=0,B2=0;
else if(step==5)A1=0,A2=1,B1=0,B2=1;
else if(step==6)A1=0,A2=0,B1=0,B2=1;
else if(step==7)A1=1,A2=0,B1=0,B2=1;
}
else //四相 8拍,MODE=0
{
if(step==0)A1=1,A2=0,B1=0,B2=0;
else if(step==1)A1=1,A2=1,B1=0,B2=0;
else if(step==2)A1=0,A2=1,B1=0,B2=0;
else if(step==3)A1=0,A2=1,B1=1,B2=0;
else if(step==4)A1=0,A2=0,B1=1,B2=0;
else if(step==5)A1=0,A2=0,B1=1,B2=1;
else if(step==6)A1=0,A2=0,B1=0,B2=1;
else if(step==7)A1=1,A2=0,B1=0,B2=1;
}
if(go) //正转
{
step++;
if(step>7)step=0;
}
else //反转
{
if(step)step--;
else step=7;
}
}
tt++;
if(ok)tt=0;
else {if(tt>200)tt=200,stop=1,lose=1;} //信号断开检测
ok=0;
}
临时借用一个IO放在主程序中取反,示波器看是否输出方波,看看主程序是否在循环。 楼主可以参考STC8G资料附录X部分:STC8G单片机取代STC15系列的注意事项:下载链接如下:
https://www.stcai.com/cp_stc8gxl
梁工 发表于 2023-2-22 09:42
临时借用一个IO放在主程序中取反,示波器看是否输出方波,看看主程序是否在循环。 ...
方波有输出,主程序循环中 STCAI-32位8051 发表于 2023-2-22 13:22
楼主可以参考STC8G资料附录X部分:STC8G单片机取代STC15系列的注意事项:下载链接如下:
https:// ...
帖子开头已经对照着手册这一段一条条改过去了 ecoo 发表于 2023-2-22 21:16
方波有输出,主程序循环中
那你说“主程序没反应”就不是了,主程序在循环中,可能是某个外设没初始化对。问题描述再细化一点,是哪个外设功能没输出? 梁工 发表于 2023-2-23 10:06
那你说“主程序没反应”就不是了,主程序在循环中,可能是某个外设没初始化对。问题描述再细化一点,是哪 ...
程序上电后输出方波,然后测量输入得pmw,在范围内正常工作,根据输入pmw宽度输出4路pmw,输入不在范围内就重新测量范围,然后写入eeprom,源程序在15w上工作正常,移植过程中未改动main、measure里面的代码。实际是只能看到上电的波形,后面输出引脚无反应了。在循环中加入直接输出,输出引脚正常输出. ecoo 发表于 2023-2-23 10:56
程序上电后输出方波,然后测量输入得pmw,在范围内正常工作,根据输入pmw宽度输出4路pmw,输入不在范围内 ...
你分两步,先测试PWM输出,给定一个占空比,看PWM是否能连续输出,能则这部分没有问题,不能则PWM部分有问题,先改好。
然后调测量的程序。 问题解决没? void EEPROM_clean(u8 address)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = address; //设置IAP低地址
IAP_ADDRH = address >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IAP_CONTR = 0; //关闭IAP功能
// IAP_CONTR=0x80; //源程序eeprom操作
//IAP_ADDRL=address;
//IAP_CMD=0x03;
//IAP_TRIG=0x46;
//IAP_TRIG=0xb9;
}
把每个IAP_TPS = 12; 取消掉,初始化配置一次就好,这个不知有没有影响,我是放初始化执行一次
然后,STC8速度比较快,所以遇到_nop_(); 你就多复制几个 _nop_(); _nop_(); _nop_(); _nop_();
页:
[1]