发新帖本帖赏金 100.00元(功能说明)我要提问
返回列表
打印
[通用8051核FLASH系列]

【HC89S003P芯片试用】水位信息采集预警

[复制链接]
4069|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tinnu|  楼主 | 2019-3-23 20:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 芯圣电子官方QQ 于 2023-7-24 14:43 编辑

(一)系统初始化
系统时钟采用内部高频晶振32M,经过2分频产生OSC时钟源:
CLKSWR = 0x51;        //选择内部高频时钟为主时钟,且内部高频RC2分频
CPU时钟是OSC时钟经过4分频,4M主频:
CLKDIV = 0x04;
系统配置:
void System_init(void)
{
        WDTCCR = 0x00;                                                //关闭看门狗
        
        while((CLKCON&0x20)!=0x20);                        //等待内部高频晶振起振
        CLKDIV = 0x02;                                                                        //CPU时钟2分频,确保在进行RC32分频时CPU时钟小于20M
        CLKSWR = 0x51;                                                                        //选择内部高频时钟为主时钟,且内部高频RC2分频
        while((CLKSWR&0xC0)!=0x40);                        //等待内部高频切换完成
        CLKDIV = 0x04;                                                                        //CPU时钟4分频
}


(二)IO口配置

IO配置不兼容传统51,比如配置P00为推挽输出:
P0M0 = 0x80|(P0M0&0x0F);


电平设置兼容传统51:
#define P0(i,n) (P0 = (n<<i)|(P0&0xFD)) 
#define PSET(p,i,n) (p = (n<<i)|(p&0xFD))


(三)UART配置
芯圣单片机的外设是类似NXP新款的那种设计哲学,可以随意指定输出引脚,不用限定IO口,布线灵活,这种设计哲学就比ST的高明一些。
UART外设理论上可以采用下载口P21和P03,但实践证明在S003P的目标板上,这种配置行不通,一旦串口与串口软件连接,单片机立即停止运行。

因此我采用P01、P02口。
void UartInit(void)
{
//        P2M0 = P2M0&0x0F|0x80;                                //P21设置为推挽输出
//        P0M1 = P0M1&0x0F|0x20;                                //P03设置为上拉输入
        P0M0 = P2M0&0x0F|0x80;                                //P01设置为推挽输出
        P0M1 = P0M1&0xF0|0x02;                                //P02设置为上拉输入
        
        TXD_MAP = 0x01;                                                //TXD映射P21
        RXD_MAP = 0x02;                                                //RXD映射P03               
        T4CON = 0x06;                                                //T4工作模式:UART1波特率发生器

    TH4 = 0xFF;
        //TL4 = 0x98;                                                        //波特率9600
        TL4 = 0xef;                                                        //波特率57600
        SCON2 = 0x02;                                                //8位UART,波特率可变
        SCON = 0x10;                                                //允许串行接收
        IE |= 0X10;                                                        //使能串口中断
        EA = 1;                                                                //使能总中断        
}
关于波特率推算,可以参考数据手册96页。

中断服务函数,事先定义结构体:
struct _UartRecStruct{
        unsigned char flag;                                //UART(完成)判断标志位
        unsigned char counter;                    //UART(接收个数)计数使用
        unsigned char Uartbuf[30];//用于存放接收收据
};

void UART1_Rpt(void) interrupt UART1_VECTOR
{
        if(SCON & 0x01)                                                //判断接收中断标志位
        {
                if(Uart1Rec.flag == 0)
                {
                        Uart1Rec.Uartbuf[Uart1Rec.counter] = SBUF;//转存8位串口接收数据
                        if(Uart1Rec.counter>=50 ||
                                Uart1Rec.Uartbuf[Uart1Rec.counter]=='\n')
                        {
                                SCON &=~ 0x10;                                //失能UART1接收
                                Uart1Rec.flag = 1;
                        }
                        else
                                Uart1Rec.counter++;
                }
                SCON &=~ 0x01;                                        //清除接收中断标志位
        }                                                                        
}
发送函数:
void SendChar(char *Uartbuf, unsigned int num)
{
        unsigned int send_i=0;
        
        IE &=~ 0x10;                                //失能UART1中断
        for(send_i= 0;send_i<=num;send_i++)
        {
                SBUF = Uartbuf[send_i];//发送8位串口数据
                while(!(SCON & 0x02));
                SCON &=~ 0x02;                        //清除发送中断标志位
        }
        IE |= 0x10;                                        //UART1中断使能
}

输出重定向:

//标准库需要的支持函数                 
struct __FILE
{
        int handle;

};

FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{      
        SendChar(f, (uint8_t)ch);
        return ch;
}
主循环内操作读取到的信息,重新打印到上位机:
if(Uart1Rec.flag)
                {
                        SendChar(Uart1Rec.Uartbuf, Uart1Rec.counter);
                        Uart1Rec.flag = 0;
                        Uart1Rec.counter = 0;
                        SCON |= 0x10;                                //UART1接收使能
                }


(四)ADC配置
adc首先要配置引脚模拟输入:

P0M0 = P0M0&0xF0|0x03;        //P00模拟输入
三个控制寄存器:
//1(使能adc)0(启动转换)0(中断标志位)0(保留位)
        //0(不输出参考电压)0(选内部参考电压)10(内部3v)
        ADCC0 = 0x82;
        Delay_ms(1);
        //00(禁止内部通道接入)00(保留位)0000(AN0通道)
        ADCC1 = 0;
        //01(转换12位,右对齐)001(2/1M的配置)011(32/2=16八分频=2M)
        ADCC2 = 0x4D;
读取adc:
int ADCRead(void)
{
        int num=0,i=0;
        char send_c[20]={0};
        
        Delay_ms(1);
        //清除标志位
        ADCC0 &= 0xDF;
        //置位启动转换
        ADCC1 |= 0x40;
        
        sprintf(send_c, "adc begin\r\n");
        SendChar(send_c, strlen(send_c));
        
        while((ADCC0&0x20)!=0x20){
//                i++;
//                if(i<=20000)
//                        return -1;
        }
        
        sprintf(send_c, "adc finish\r\n");
        SendChar(send_c, strlen(send_c));
        
        ADCC0 &=~ 0x20;
        //读取数据
        num = ADCRH;
        num = num<<8;
        num |= ADCRL;
        
        return num;
}


(五)整体设置
读取ADC值,上传:

send_d = ADCRead();
                sprintf(send_c, "adc:%d\r\n", send_d);
                SendChar(send_c, strlen(send_c));
超过阈值,点亮警示灯:
  P0M2 = 0x80|(P0M0&0xF0);
                if(send_d >= 0x8ff)
                        PSET(P0,4,1);
                else
                        PSET(P0,4,0);


使用特权

评论回复

打赏榜单

芯圣电子官方QQ 打赏了 100.00 元 2019-04-08
理由:001P试用二等奖

沙发
hayden0| | 2019-3-24 14:51 | 只看该作者
为什么我的可以使用P21和P03,你确定不行?
https://bbs.21ic.com/icview-2647562-1-1.html

使用特权

评论回复
板凳
键盘手没手| | 2019-4-30 23:42 | 只看该作者
能拿奖都是大神啊,。

使用特权

评论回复
地板
键盘手没手| | 2019-4-30 23:42 | 只看该作者
给大神点赞!

使用特权

评论回复
5
rickluo| | 2019-5-8 13:26 | 只看该作者
深圳市集万讯电子技术有限公司华大半导体 MCU核心代理商,专业MCU推广商,为客户提供华大全系列MCU:
HC32F003C4PA-TSSOP20
HC32F003C4UA-SFN20TR
HC32F005C6UA-SFN20TR
HC32L110C6UA-SFN20TR
HC32L130J8TA-LQ48
HC32L130F8UA-QFN32TR
HC32L136K8TA-LQ64
等大量现货库存,专业、权威、全面技术支持,有效提高您产品开发效率缩短开发周期;

江苏润石科技有限公司
专业模拟器件厂家,代表产品运算放大器(运放)全面兼容Ti、Microchip、圣邦微等品牌;


成都盛芯微科技有限公司

BLE蓝牙专业,代表型号SYD8811、SYD8821全面兼容NORDIC

欢迎来电咨询、索样:

TEL:0755-83764413   
QQ: 1529637660

使用特权

评论回复
6
yzq13246068880| | 2019-5-8 14:54 | 只看该作者
非常不错,顶顶顶

使用特权

评论回复
7
linguanghua| | 2019-6-14 14:52 | 只看该作者
不错,参考参考还是不错的。

使用特权

评论回复
发新帖 本帖赏金 100.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

71

帖子

0

粉丝