416369123 发表于 2012-3-28 17:19:57

STC12C5A60S2单片机怎么用自带的模数功能啊

哪个大师能帮忙解说一下,小弟是单片机初学者

hellosky 发表于 2012-3-28 17:38:39

STC网站有例程的。

Felix257 发表于 2012-3-28 17:40:19

是的,官网有例程,datasheet里也有这部分的内容啊

BXAK 发表于 2012-3-28 18:28:21

本帖最后由 BXAK 于 2012-3-28 18:31 编辑

到STC官网下载 STC-ISP V6.15(免安装单文件只几百KB大小),把它当作“STC单片机工具箱”:

1、1T、12T系列所有硬件资源使用范例:C + 汇编。复制粘贴就可使用,进行实验;
2、1T、12T系列延时计算;
3、各系列的头文件都有;
4、芯片选型,各型号的ROM、RAM、EEPROM等等一目了然。

416369123 发表于 2012-3-28 22:33:44

Felix257 发表于 2012-3-28 17:40 static/image/common/back.gif
是的,官网有例程,datasheet里也有这部分的内容啊

谢谢哈!

416369123 发表于 2012-3-28 22:34:15

BXAK 发表于 2012-3-28 18:28 static/image/common/back.gif
到STC官网下载 STC-ISP V6.15(免安装单文件只几百KB大小),把它当作“STC单片机工具箱”:

1、1T、12T系 ...

谢谢哈!

角度361 发表于 2012-4-1 17:21:51

例程改的,P1.1为一个通道,时钟改为12M,波特率9600,串口发送数据,取10位ADC的高8位

//---------------------------------------------------------------------
//#include <REG52.H>
#include <intrins.H>
#include "STC12C5A60S2.H"
//---------------------------------------------------------------------
typedef    unsigned char   INT8U;
typedef    unsigned int    INT16U;
//---------------------------------------------------------------------
//以下选择 ADC 转换速率,只能选择其中一种
                        //            SPEED1 SPEED0A/D转换所需时间
#define AD_SPEED   0x60 //0110,0000   1      1   70 个时钟周期转换一次,
                        //CPU工作频率21MHz时 A/D转换速度约 300KHz
//#define AD_SPEED   0x40 //0100,0000   1      0   140 个时钟周期转换一次
//#define AD_SPEED   0x20 //0010,0000   0      1   280 个时钟周期转换一次
//#define AD_SPEED   0x00 //0000,0000   0      0   420 个时钟周期转换一次
//---------------------------------------------------------------------
void initiate_RS232 (void);         //串口初始化
void Send_Byte(INT8U one_byte);   //发送一个字节
INT8U get_AD_result(INT8U channel);
void delay(INT8U delay_time);       //延时函数
//---------------------------------------------------------------------
void main()
{
    INT16U ADC_result;

    initiate_RS232();               //波特率 = 115200
    P1ASF = 0x02;                   //0000,0010, 将 P1.1 置成模拟口

//ADRJ = AUXR1^2:
//    0: 10 位A/D 转换结果的高8 位放在ADC_RES 寄存器, 低2 位放在ADC_RESL 寄存器
//    1: 10 位A/D 转换结果的最高2 位放在ADC_RES 寄存器的低2 位, 低8 位放在ADC_RESL 寄存器
    AUXR1 &= ~0x04;               //0000,0100, 令 ADRJ=0
//    AUXR1 |= 0x04;                  //0000,0100, 令 ADRJ=1

    ADC_CONTR |= 0x80;            //1000,0000 打开 A/D 转换电源
    while(1)
    {
      ADC_result = get_AD_result(1);//P1.1 为 A/D 当前通道, 测量并发送结果
//      Send_Byte(0xCC);            //为便于观察, 发送 2 个 0xAA
//      Send_Byte(0xCC);
      Send_Byte(ADC_result);
//      delay(0xff);
    }
}
//---------------------------------------------------------------------
void delay(INT8U delay_time)      // 延时函数
{
    INT16U n;
    while(delay_time--)
    {
      n = 6000;
      while(--n);
    }
}
//---------------------------------------------------------------------
#define Fosc 12000000
#define BAUD 9600                //波特率
#define RELOAD_115200 (256 - (Fosc/16*10/BAUD+5)/10 )   //1T模式, 波特率加倍
#define BRTx12_enable() AUXR |= 0x04   //BRT 独立波特率发生器的溢出率快 12 倍
#define BRT_start()   AUXR |= 0x10   //启动独立波特率发生器 BRT 计数。

void initiate_RS232 (void)          //串口初始化
{
    ES = 0;                         //禁止串口中断
    SCON = 0x50;                  //可变波特率. 8位无奇偶校验

    AUXR |= 0x01;                   //使用独立波特率发生器
    PCON |= 0x80;                   //波特率加倍
    BRTx12_enable();                //BRT 独立波特率发生器的溢出率快 12 倍
    BRT = RELOAD_115200;            //设置独立波特率发生器 BRT 的自动重装数
    BRT_start();                  //启动独立波特率发生器 BRT 计数。

    ES = 1;
}
//---------------------------------------------------------------------
void Send_Byte(INT8U one_byte)      //发送一个字节
{
    TI = 0;                         //清零串口发送中断标志
    SBUF = one_byte;
    while (TI == 0);
    TI = 0;                         //清零串口发送中断标志
}
//---------------------------------------------------------------------
INT8U get_AD_result(INT8U channel)
{
    INT8U AD_finished=0;            //存储 A/D 转换标志

    ADC_RES = 0;
    ADC_RESL = 0;

    channel &= 0x07;                //0000,0111 清0高5位
    ADC_CONTR = AD_SPEED;
    _nop_();
    ADC_CONTR |= channel;         //选择 A/D 当前通道
    _nop_();
    ADC_CONTR |= 0x80;            //启动 A/D 电源
    delay(1);                     //使输入电压达到稳定
    ADC_CONTR |= 0x08;            //0000,1000 令 ADCS = 1, 启动A/D转换,
    AD_finished = 0;
    while (AD_finished ==0 )      //等待A/D转换结束
    {
      AD_finished = (ADC_CONTR & 0x10); //0001,0000 测试A/D转换结束否
    }
    ADC_CONTR &= 0xE7;            //1111,0111 清 ADC_FLAG 位, 关闭A/D转换,

    return (ADC_RES);               //返回 A/D 高 8 位转换结果
}

jetli 发表于 2012-4-1 17:32:00

to“时钟改为12M,波特率9600”,这样不会误码么

416369123 发表于 2012-4-2 19:51:01

角度361 发表于 2012-4-1 17:21 static/image/common/back.gif
例程改的,P1.1为一个通道,时钟改为12M,波特率9600,串口发送数据,取10位ADC的高8位

//--------------- ...

把这个程序下载到单片机内,用串口调试时不停地接收00是什么原因?

ddny2008 发表于 2012-4-2 19:56:47

STC的说明书上写得很详细

chenhua1991 发表于 2012-4-2 22:07:38

416369123 发表于 2012-4-2 19:51 static/image/common/back.gif
把这个程序下载到单片机内,用串口调试时不停地接收00是什么原因?

这应该是串口助手波特率没调好

chenhua1991 发表于 2012-4-2 22:09:42

发个我最近刚写的用STC自带的AD功能读取紫外传感器的程序给你参考下吧
#include<reg52.h>
#include "uvm30.h"

sfr ADC_CONTR=0xbc;          //定义ADC相应寄存器地址
sfr P1ASF=0x9d;
sfr ADC_RES=0xbd;
sfr ADC_RESL=0xbe;
sfr AUXR1=0xa2;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;

/****************************************************************
函数名称:UVM30_Sample
函数功能:紫外线强度采样
入口参数:无
出口参数:uvi    //紫外线强度,0-11
备 注:
*****************************************************************/
unsigned char UVM30_Sample()
{
        int adc_result;
        unsigned char uvi;
        P1ASF=0x01;                   //设置P1.0作为模拟功能AD使用
        P1M0|=0x01;         //设置P1.0为开漏模式
        P1M1|=0x01;

        ADC_CONTR=0xe0;//设置ADC电源开,转换速率为11,转换通道为P1.0       

        ADC_RES=0;
        ADC_RESL=0;
        ADC_CONTR|=0x08; //开始转换
        while(!(ADC_CONTR&0x10));                //判断转换是否结束

        adc_result=ADC_RES;
        adc_result=(adc_result<<2)|ADC_RESL;          //将转换得到的10位数据赋给adc_result变量
       
        ADC_CONTR=0x00;          //清空ADC_CONTR寄存器的所有位
        adc_result&=0x03ff;
        adc_result=(float)adc_result*5000/1024;          //计算得到电压值,单位mV

        if(adc_result<=50)                   //通过AD转换得到的电压值换算出紫外线强度
                uvi=0;
        else if(adc_result<=227)
                uvi=1;
        else if(adc_result<=318)
                uvi=2;
        else if(adc_result<=408)
                uvi=3;
        else if(adc_result<=503)
                uvi=4;
        else if(adc_result<=606)
                uvi=5;
        else if(adc_result<=696)
                uvi=6;
        else if(adc_result<=795)
                uvi=7;
        else if(adc_result<=881)
                uvi=8;
        else if(adc_result<=976)
                uvi=9;
        else if(adc_result<=1079)
                uvi=10;
        else
                uvi=11;
        return uvi;
}

416369123 发表于 2012-4-2 22:40:38

chenhua1991 发表于 2012-4-2 22:09 static/image/common/back.gif
发个我最近刚写的用STC自带的AD功能读取紫外传感器的程序给你参考下吧
#include
#include "uvm30.h"


谢谢你哈

角度361 发表于 2012-4-5 10:57:01

本帖最后由 角度361 于 2012-4-5 11:03 编辑

jetli 发表于 2012-4-1 17:32 static/image/common/back.gif
to“时钟改为12M,波特率9600”,这样不会误码么

我手头就有12M的,就先用的12M,过后改成过11.0592M,与12M相比没什么变化啊,datasheet上说有生么BRT独立波特率发生器,也没看懂到底可不可以用12M

asdf1776 发表于 2012-4-5 11:06:12

角度361 发表于 2012-4-5 10:57 static/image/common/back.gif
我手头就有12M的,就先用的12M,过后改成过11.0592M,与12M相比没什么变化啊,datasheet上说有生么BRT独 ...

晶振改了不影响通讯???

BXAK 发表于 2012-4-5 11:22:35

asdf1776 发表于 2012-4-5 11:06 static/image/common/back.gif
晶振改了不影响通讯???

串口异步通信允许一定程度上的误差,具体是百分之多少忘了

角度361 发表于 2012-4-5 11:33:29

asdf1776 发表于 2012-4-5 11:06 static/image/common/back.gif
晶振改了不影响通讯???

仔细看了一下此单片机的datasheet,波特率计算如下:
我的程序中采用1T模式, 波特率加倍
12M时则有:
RElOAD=256-INT(12000000/16/9600+0.5)=256-78=178
BAND=12000000/(256-178)/16=9615
误差=(9615-9600)/9600*100%=0.156%
11.0592M时则有
RELOAD=256-72
BAND=9600
误差=0%
因此,在选取波特率9600时,此单片机选用12M晶振做串口通信还可以。

角度361 发表于 2012-4-5 11:34:49

416369123 发表于 2012-4-2 19:51 static/image/common/back.gif
把这个程序下载到单片机内,用串口调试时不停地接收00是什么原因?

在P1.1接入小于5V电压试试呢

asdf1776 发表于 2012-4-5 13:23:50

呵呵,真没注意过这个误差,一直by the book

416369123 发表于 2012-4-5 13:34:39

角度361 发表于 2012-4-5 11:34 static/image/common/back.gif
在P1.1接入小于5V电压试试呢

试了,还是不行,波特率用的是9600,然后试了其他波特率虽然发送的字符变了,但是改变电压还是没变化

角度361 发表于 2012-4-5 14:11:58

416369123 发表于 2012-4-5 13:34 static/image/common/back.gif
试了,还是不行,波特率用的是9600,然后试了其他波特率虽然发送的字符变了,但是改变电压还是没变化 ...

main函数改为
void main()
{
    INT16U ADC_result;

    initiate_RS232();               //波特率 = 115200
    P1ASF = 0x02;                   //0000,0010, 将 P1.1 置成模拟口

//ADRJ = AUXR1^2:
//    0: 10 位A/D 转换结果的高8 位放在ADC_RES 寄存器, 低2 位放在ADC_RESL 寄存器
//    1: 10 位A/D 转换结果的最高2 位放在ADC_RES 寄存器的低2 位, 低8 位放在ADC_RESL 寄存器
    AUXR1 &= ~0x04;               //0000,0100, 令 ADRJ=0
//    AUXR1 |= 0x04;                  //0000,0100, 令 ADRJ=1

    ADC_CONTR |= 0x80;            //1000,0000 打开 A/D 转换电源
    while(1)
    {
      ADC_result = get_AD_result(1);//P1.1 为 A/D 当前通道, 测量并发送结果
      Send_Byte(0xAA);            //为便于观察, 发送 2 个 0xAA
      Send_Byte(0xAA);
      Send_Byte(ADC_result);
      delay(0xff);
    }
}
看看是否能收到两个AA,我是帮我同学做完这个好用就立马发到坛子上了啊

416369123 发表于 2012-4-5 23:08:55

角度361 发表于 2012-4-5 14:11 static/image/common/back.gif
main函数改为
void main()
{


虽然还是不能收到aa,但还是要谢谢你哈,发奋学串口通讯去,嘿嘿

角度361 发表于 2012-4-6 10:05:41

416369123 发表于 2012-4-5 23:08 static/image/common/back.gif
虽然还是不能收到aa,但还是要谢谢你哈,发奋学串口通讯去,嘿嘿

不客气,不能收到aa那就是串口没调通,加油

a312835782 发表于 2012-4-6 15:41:02

官方手册有写的,可以看看

lmhws 发表于 2012-4-20 00:17:16

chenhua1991 发表于 2012-4-2 22:09 static/image/common/back.gif
发个我最近刚写的用STC自带的AD功能读取紫外传感器的程序给你参考下吧
#include
#include "uvm30.h"


请教一个问题(发个我最近刚写的用STC自带的AD功能读取紫外传感器的程序给你参考下吧
),sec例程中没有定义AUXR1地址,而你也仅仅定义地址,并没有设定adrj,请问为什么

chenhua1991 发表于 2012-4-20 00:25:15

lmhws 发表于 2012-4-20 00:17 static/image/common/back.gif
请教一个问题(发个我最近刚写的用STC自带的AD功能读取紫外传感器的程序给你参考下吧
),sec例程中没有 ...

adrj默认就是0吧,我的目的就是读取10位的转换值,当ADRJ为0的时候ADC_RES存放高8位,低2位存在ADC_RESL的低2位中,所以没必要设定ADRJ,保持默认就行了

ym7205 发表于 2012-6-13 10:03:56

asdf1776 发表于 2012-4-5 11:06 static/image/common/back.gif
晶振改了不影响通讯???

会影响的,乱码的,我试过的,

loyoid 发表于 2012-6-29 17:07:21

MARK   也想用来做一个电压表!
页: [1]
查看完整版本: STC12C5A60S2单片机怎么用自带的模数功能啊