找回密码
 立即注册
查看: 2793|回复: 9

STC8G1K08片子, 单个ADC 读时没问题,读两个ADC时就不行.试了...

[复制链接]

该用户从未签到

1

主题

7

回帖

31

积分

新手上路

积分
31
发表于 2023-3-6 12:25:27 | 显示全部楼层 |阅读模式
STC8G1K08片子, 单个ADC 读时没问题,读两个ADC时就不行.试了一天都不成,百思不得其解,不知问题在哪?请帮助!
片子STC8G1K08 SOP16
用这个片子遇到几个问题,先是用串口时(串口用的定时器1),这时发现定时器0,不能用,否则 TR0 = 1开始计时,串口就不能通信!!!!不知为何?后来只好改用定时器2。
再后来就是ADC问题。发现 单独读时没问题,读两个时就不行,我这里读ADC0和ADC1。两个数据相同都是ADC1的数据。我怕在一起读出的问题,我再主程序里,设置延时分开读,隔一秒读AD0,再隔一秒读ADC1,都还不行。但发现上电第一次读取两个数据正常,之后再读,就不正常,之前12系列都没问题,这个8G折腾人!试了一天都不成,百思不得其解,不知问题在哪?请帮助!有朋友遇到的,请帮回复下,洗耳恭听!

//2023-03-01
//STC8G1K08 SOP16          33.1776MHz  1T
//
///*************  功能说明    **************
//使用P35,P36;P37输出3路PWM。 P37输出PWM1,P35,P36输出PWM2和PWM3.
//使用P10,P11输入ADC. 采集外部电位控制
//串口1配置为1200bps, 8,n, 1, 切换到P3.0 P3.1, 下载后就可以直接测试. 主时钟为33.1776MHZ,
//特别说明:串口1,必须用定时器1做波特率发生器;
//定时器0,不能用,否则 TR0 = 1开始计时,串口就不能通信!!!!不知为何?         pwm改选了定时器2.

//******************************************/

#include <STC8G.h>
#include<stdio.h>
#include<string.h>
#include<intrins.h>
//

typedef     unsigned char   u8;
typedef     unsigned int    u16;
typedef     unsigned long   u32;
//

/****************************** 串口 ***********************************/
u8 flag,m,i=0;
u8 Rx[2];
u8 fs[20];
void Timer2Init(void);
void UART1_init();
void UART1_TxByte(u8 dat);           //发送一个字节
void PrintString(u8 *puts); //发送一个字符串
//
///*************  本地变量和声明    **************/
u8 t=0;
bit tmsflag=0;
u16 tms=0;


u8 ADCdim,ADCccm;
void ADC_init();
u16 ADCRead(u8 channel);

//
/********************主函数 **************************/
void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x03;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;

    UART1_init();

        Timer2Init();
       
        ADC_init();

    EA = 1;

    while (1)
        {
//         if(flag==1)   //先串口测试
//                {
//                flag=0;
//                 PrintString("接收"); //发送一个字符串        "接收\r\n"               
//                 UART1_TxByte(Rx[0]);           //发送一个字节
//                 UART1_TxByte(Rx[1]);           //发送一个字节
//        
//                ADCdim=ADCRead(0) ;
////                if(ADCdim<5){P35=0;P36=0;        AUXR &= 0xef;}        else AUXR |= 0x10;
//                ADCccm=ADCRead(1) ;
//                UART1_TxByte(ADCdim);           //发送一个字节
//                UART1_TxByte(ADCccm);           //发送一个字节
////          ADCdim=Rx[0];            ADCccm=Rx[1];
//           }

                if(tms==20000)          //延时间隔长时间分开读取                  测试
                {       
                        ADCdim=ADCRead(0) ;                //读取ADC0
                        ADCdim=ADCRead(0) ;                //读取ADC0

                                PrintString("ok"); //发送一个字符串        "接收ok\r\n"
                                UART1_TxByte(ADCdim);           //发送一个字节
                }

                if(tmsflag==1)
                {        tmsflag=0;
                        ADCccm=ADCRead(1) ;           //读取ADC1
                        ADCccm=ADCRead(1) ;           //读取ADC1

                        if(ADCdim<3){P35=0;P36=0;        AUXR &= 0xef;}        else AUXR |= 0x10;
               

//                        UART1_TxByte(ADCdim);           //发送一个字节
                        UART1_TxByte(ADCccm);           //发送一个字节
           }
                  tms++; if(tms>40000) { tmsflag=1;tms=0;         }                   //延时测试

        }
}


//**************改定时器2 发送3PWM 信号********
void Timer2Init(void)                //1微秒@6.000MHz
{
        AUXR |= 0x04;        //定时器时钟1T模式
        T2L = 0xFF;                //设置定时初始值
        T2H = 0xFF;                //设置定时初始值
        AUXR |= 0x10;        //定时器2开始计时
        IE2 = 0x04;     //使能定时器中断
}

void  TM2_Isr() interrupt 12
{       
                if(t<ADCdim)  P37=1; else P37=0;           //PWM1控制

                if(t<ADCccm)    P35=1; else P35=0;           //PWM2,PWM3控制
                if(t>ADCccm+2)        P36=1; //else P36=0;
                if(t>252) P36=0;
             t++;          if(t>=255)  t=0;
}


////******ADC采集转换************************************************************

void ADC_init()
{   
        P1M0 = 0x00;                                //设置P1.0为ADC口
    P1M1 = 0x03;                                                                // 设置P1.0,P1.1为ADC口

    P_SW2 |= 0x80;
    ADCTIM = 0x3f;                              //设置ADC内部时序
     P_SW2 &= 0x7f;
    ADCCFG = 0x07;                              //设置ADC时钟为系统时钟/2/16        只取高8位结果
    ADC_CONTR = 0x80;                           //使能ADC模块
        _nop_(); _nop_(); _nop_(); _nop_();_nop_();   
//         EADC = 1;  
}


u16 ADCRead(u8 channel)
{
    int res;
    ADC_CONTR = ADC_CONTR|channel|0xc0;         //启动AD转换
    _nop_();
    _nop_();
    while (!(ADC_CONTR & 0x20));                //查询ADC完成标志
    ADC_CONTR &= ~0x20;                         //清完成标志
//          UART1_TxByte(ADC_RES);         UART1_TxByte(ADC_RESL);
//  res = (ADC_RES << 8) | ADC_RESL;            //读取ADC结果
        res = ADC_RES;                                                                //只取高8位结果
    return res;
        _nop_(); _nop_(); _nop_();
}


//******串口*****************

void UART1_init()                  //1200bps@33.1776MHz
{         
        SCON = 0x50;                //8位数据,可变波特率
        AUXR &= 0xBF;                //定时器时钟12T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设置定时器模式
        TL1 = 0xC0;                //设置定时初始值
        TH1 = 0xFD;                //设置定时初始值
        ET1 = 0;                //禁止定时器%d中断
        TR1 = 1;                //定时器1开始计时
        EA=1;
        ES=1;         
}

//===串口1发送。
bit B_TX1_Busy; //发送忙标志
void    UART1_TxByte(u8 dat)
{
    SBUF = dat;
    B_TX1_Busy = 1;
    while(B_TX1_Busy);
}

//========================================================================
// 函数: void PrintString1(u8 *puts)
// 描述: 串口1发送字符串函数。
// 参数: puts:  字符串指针.
// 返回: none.
//========================================================================
void PrintString(u8 *puts) //发送一个字符串
{
    for (; *puts != 0;  puts++)   UART1_TxByte(*puts);  //遇到停止符0结束
}       

//=====串口1中断==================================================================
void com() interrupt  4
{
        if(RI)
        {        RI=0;
                Rx[i]=SBUF;i++;
                if(i>=2)
                {
                        flag=1;
                        i=0;
                }

//                m=SBUF;
//                fs[i]=m;i++;
//                if(m=='a')
//                {
//                        flag=1;
//                        i=0;
//                }

        }

        if(TI)
    {
        TI = 0;
        B_TX1_Busy = 0;
    }
}

////*****定时器0 发送3PWM 信号 *****//定时器0开始计时,串口就不能通信!!!!
//void Timer0Init(void)                //1微秒@6.000MHz
//{
//        AUXR |= 0x80;                //定时器时钟1T模式
//        TMOD &= 0xF0;                //设置定时器模式
//        TL0 = 0xFf;                //设置定时初始值
//        TH0 = 0xFF;                //设置定时初始值
//        TF0 = 0;                //清除TF0标志
//        TR0 = 1;                //定时器0开始计时          打开时串口就不能通信!!!!
//}
//
//void TM0_Isr() interrupt 1
//{        if(t<ADCdim)         P37=1; else P37=0;
//        if(t<ADCccm)    P35=1; else P35=0;
//        if(t>ADCccm+2)        P36=1; //else P36=0;
//        if(t>252) P36=0;
//    t++;
//        if(t>=255)           t=0;
//}






pwm3.zip

55.27 KB, 下载次数: 63

回复 送花

使用道具 举报

该用户从未签到

45

主题

2910

回帖

6540

积分

超级版主

积分
6540
发表于 2023-3-6 13:16:21 | 显示全部楼层
定时器都是独立的外设,不会受别的外设影响的,要仔细查下程序,或者用STC的官方例程测试。
只有一个ADC外设,通过多选1开关选择通道,所以基本不会出现单通道可以ADC、多通道不行的问题,出现了,基本是电路的问题。
刚在另一个论坛有人也做两路ADC说不行,其中一路ADC悬空,发现的“不正常”,这是典型的应用错误。
ADC输入悬空的通道,采样时,采样电容没法充放电,所以看似受上一个通道的影响。

该用户从未签到

1

主题

7

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2023-3-6 13:23:49 | 显示全部楼层
梁工 发表于 2023-3-6 13:16
定时器都是独立的外设,不会受别的外设影响的,要仔细查下程序,或者用STC的官方例程测试。
只有一个ADC外 ...

两通道都有接电位控制器。问题是,如果程序里单独一路ADC没问题。
还有通过串口监视,上电第一次两个都正常,之后ADC1正常,ADC0就不正常,并且等于ADC1.很奇怪

该用户从未签到

1

主题

7

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2023-3-6 13:26:16 | 显示全部楼层
梁工 发表于 2023-3-6 13:16
定时器都是独立的外设,不会受别的外设影响的,要仔细查下程序,或者用STC的官方例程测试。
只有一个ADC外 ...

还有,只要一开启定时器0,串口就不能收发了。

点评

请仔细检查程序吧,定时器0跟串口一点关系都没有的。 ADC可以使用STC官方例程,直接下载HEX文件测试。  详情 回复 发表于 2023-3-6 13:40

该用户从未签到

45

主题

2910

回帖

6540

积分

超级版主

积分
6540
发表于 2023-3-6 13:40:36 | 显示全部楼层
高山入云 发表于 2023-3-6 13:26
还有,只要一开启定时器0,串口就不能收发了。

请仔细检查程序吧,定时器0跟串口一点关系都没有的。
ADC可以使用STC官方例程,直接下载HEX文件测试。

该用户从未签到

45

主题

2910

回帖

6540

积分

超级版主

积分
6540
发表于 2023-3-6 13:49:43 | 显示全部楼层
这是ADC测试程序,请解压缩后直接下载“ADC相关程序-STC8G1K08-20PIN”里的“01-15路ADC转换-BandGap-串口1(P3.7)返回结果-C语言”里的HEX文件测试,串口返回结果,你只需要关心你要的通道即可,别的通道不用理会。下载时选择主频11.0592MHz,串口助手波特率115200,8,n,1. 文本接收。

STC8G系列-ADC相关程序.rar (341.32 KB, 下载次数: 90)

该用户从未签到

1

主题

7

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2023-3-6 13:55:55 | 显示全部楼层
梁工 发表于 2023-3-6 13:49
这是ADC测试程序,请解压缩后直接下载“ADC相关程序-STC8G1K08-20PIN”里的“01-15路ADC转换-BandGap-串口1 ...

好,谢谢。我试下

该用户从未签到

1

主题

7

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2023-3-6 14:40:01 | 显示全部楼层
梁工 发表于 2023-3-6 13:49
这是ADC测试程序,请解压缩后直接下载“ADC相关程序-STC8G1K08-20PIN”里的“01-15路ADC转换-BandGap-串口1 ...

试了下,您的可以,我参考下您的程序。谢谢!

该用户从未签到

1

主题

7

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2023-3-6 16:01:25 | 显示全部楼层
查看梁工的范例,终于解决了。谢谢梁工!
错在这一句:    ADC_CONTR = ADC_CONTR|channel|0xc0;         //启动AD转换
改为:ADC_CONTR = channel|0xc0;         //启动AD转换就好了。
上电第一次对的,那是因为通道值为0,当再读完第1口后,ADC_CONTR寄存器中的通道1值没有清除掉,所以才出现读第0口和第1口一样的结果.

该用户从未签到

550

主题

9221

回帖

1万

积分

管理员

积分
13912
发表于 2023-3-6 16:30:24 | 显示全部楼层
还是要用 STC-USB Link1D 来仿真STC8/STC32,这些问题就容易查到了
1.png

https://www.stcaimcu.com/forum.p ... &extra=page%3D2



回复 支持 1 反对 0 送花

使用道具 举报

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2024-4-26 23:20 , Processed in 0.071402 second(s), 68 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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