返回列表 发新帖本帖赏金 100.00元(功能说明)
打印

[资源共享] 【HC89S003P芯片试用】水位信息采集预警

[复制链接]
2596|7
跳转到指定楼层
楼主
(一)系统初始化
系统时钟采用内部高频晶振32M,经过2分频产生OSC时钟源:
  1. CLKSWR = 0x51;        //选择内部高频时钟为主时钟,且内部高频RC2分频
复制代码
CPU时钟是OSC时钟经过4分频,4M主频:
  1. CLKDIV = 0x04;
复制代码
系统配置:
  1. void System_init(void)
  2. {
  3.         WDTCCR = 0x00;                                                //关闭看门狗
  4.        
  5.         while((CLKCON&0x20)!=0x20);                        //等待内部高频晶振起振
  6.         CLKDIV = 0x02;                                                                        //CPU时钟2分频,确保在进行RC32分频时CPU时钟小于20M
  7.         CLKSWR = 0x51;                                                                        //选择内部高频时钟为主时钟,且内部高频RC2分频
  8.         while((CLKSWR&0xC0)!=0x40);                        //等待内部高频切换完成
  9.         CLKDIV = 0x04;                                                                        //CPU时钟4分频
  10. }
复制代码


(二)IO口配置

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


电平设置兼容传统51:
  1. #define P0(i,n) (P0 = (n<<i)|(P0&0xFD))
  2. #define PSET(p,i,n) (p = (n<<i)|(p&0xFD))
复制代码


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

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

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

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

  1. void UART1_Rpt(void) interrupt UART1_VECTOR
  2. {
  3.         if(SCON & 0x01)                                                //判断接收中断标志位
  4.         {
  5.                 if(Uart1Rec.flag == 0)
  6.                 {
  7.                         Uart1Rec.Uartbuf[Uart1Rec.counter] = SBUF;//转存8位串口接收数据
  8.                         if(Uart1Rec.counter>=50 ||
  9.                                 Uart1Rec.Uartbuf[Uart1Rec.counter]=='\n')
  10.                         {
  11.                                 SCON &=~ 0x10;                                //失能UART1接收
  12.                                 Uart1Rec.flag = 1;
  13.                         }
  14.                         else
  15.                                 Uart1Rec.counter++;
  16.                 }
  17.                 SCON &=~ 0x01;                                        //清除接收中断标志位
  18.         }                                                                       
  19. }
复制代码
发送函数:
  1. void SendChar(char *Uartbuf, unsigned int num)
  2. {
  3.         unsigned int send_i=0;
  4.        
  5.         IE &=~ 0x10;                                //失能UART1中断
  6.         for(send_i= 0;send_i<=num;send_i++)
  7.         {
  8.                 SBUF = Uartbuf[send_i];//发送8位串口数据
  9.                 while(!(SCON & 0x02));
  10.                 SCON &=~ 0x02;                        //清除发送中断标志位
  11.         }
  12.         IE |= 0x10;                                        //UART1中断使能
  13. }

复制代码
输出重定向:

  1. //标准库需要的支持函数                 
  2. struct __FILE
  3. {
  4.         int handle;

  5. };

  6. FILE __stdout;      
  7. //定义_sys_exit()以避免使用半主机模式   
  8. _sys_exit(int x)
  9. {
  10.         x = x;
  11. }
  12. //重定义fputc函数
  13. int fputc(int ch, FILE *f)
  14. {      
  15.         SendChar(f, (uint8_t)ch);
  16.         return ch;
  17. }
复制代码
主循环内操作读取到的信息,重新打印到上位机:
  1. if(Uart1Rec.flag)
  2.                 {
  3.                         SendChar(Uart1Rec.Uartbuf, Uart1Rec.counter);
  4.                         Uart1Rec.flag = 0;
  5.                         Uart1Rec.counter = 0;
  6.                         SCON |= 0x10;                                //UART1接收使能
  7.                 }
复制代码


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

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


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

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


打赏榜单

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

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

评论

键盘手没手 2019-4-30 23:42 回复TA
6666 
板凳
| 2019-4-30 23:42 | 只看该作者
能拿奖都是大神啊,。
地板
| 2019-4-30 23:42 | 只看该作者
给大神点赞!
5
| 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
| 2019-5-8 14:54 | 只看该作者
非常不错,顶顶顶
7
| 2019-6-14 14:52 | 只看该作者
不错,参考参考还是不错的。
扫描二维码,随时随地手机跟帖
返回列表 发新帖 本帖赏金 100.00元(功能说明)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表
广西快3 内蒙古快3 河北快3 甘肃快3 江西快3 河南快3 安徽快3 广西快3 pk10开奖 贵州快3