PIC16F877A单片机PPM调制的激光通信Proteus仿真及源程序

2019-11-09来源: 51hei关键字:PIC16F877A  单片机  PPM调制  激光通信

软件:
MPLAB X IDE v4.15编译    proteus 8.6仿真.
1、仿真电路图;
2、发送和接收源程序加注释。
请看注释。
原理:
1)ADC读取并用led显示ADC读数,并通过usart进行输出。
2)通过PPM原理进行通讯传输到另外一个单片机,LED显示接收的值。
具体请看附件
希望大家顶一下。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
 
1、发送模块:读取ADC数值,LED显示10位ADC值。并通过PPM发送。
2、接收模块:PPM接收到的数据。LED显示接收的ADC值(10bits)

基于PIC单片机的PPM调制激光通信收发器

PPM (pulse position modulation) 脉冲位置调制。

  • 通过改变脉冲的位置来传输不同的数据。

如图1、

  • PPM的编码:

如图、利用单片机的PWM功能产生PWM1和PWM2连个脉冲。

利用数字电路合成PPM脉冲。

可以看出当PWM1的占空比是0时,PPM如下图的A,

PWM1的占空比是1时,PPM如下图的B,



  • PPM的合成:

如第一个图可知,PPM可以将PPM1求反后和PWM2相与得到。

故设计如上发送模块。接收模块结果波形整形送到单片机处理。

  • PPM发送的数据(16位的双字节数)。

定义占空比一定的脉冲为发送的数据。

发送0,   0,   0,   0-3, 4-7,   8-11, 12-15

前面是头,可以提供接收PPM的单个周期。

  • PPM接收。

PPM接收到的数据是:

由图中知道

  • 不用,作为启动接收。

  • 就是波形的周期

    (3-2)即3测量的宽度减去波形的周期的等于0-3对应的PWM脉宽1

(4+脉宽1-2)即4测量的宽度加上脉宽1减去波形的周期的等于4-7对应的PWM脉宽2

(5+脉宽2-2)即5测量的宽度加上脉宽2减去波形的周期的等于8-11对应的PWM脉宽3

(6+脉宽3-2)即6测量的宽度加上脉宽3减去波形的周期的等于12-15对应的PWM脉宽4

在将四个半字节数合成2个字节16位的值。

单片机源程序如下:

#include "sys.h"

#include        /* For uint8_t definition */

#include       /* For true/false definition */

#include

#define AKING PORTCbits.RC0

const uint8_t uart_disp1[]={"ADC result(DEC) is:"};      //uart DISP

void usart_send_8bits(uint8_t send_data);

void ppm_send_unit(uint8_t send_data);

void time1_init();


uint16_t adc_read()                         

{

    ADCON1=0x80;                //fosc/2,A口都是AD口,Vref=VDD

           ADCON0=0x01;                //AN0进行转换,允许转换

                                //ADFM  ADCS2 --  --  PCFG3   PCFG2   PCFG1  PCFG0

                                //        1      0             0      0      0      0

                                //ADCS1 ADCS0  CHS2 CHS1 CHS0  GO/DONE  --  ADON

                                //  0     0     0    0     0     0            1

    __delay_ms(2);              //delay 

        GO=0x01;                                                          //开始AD转换

    while(GO);                                                        //是否转换完毕,GO=0转换完毕  

        uint16_t adc_result=(uint16_t)ADRESH<<8 |ADRESL;    //转换结果,10bits

    return adc_result;                  //return ADC results

}

void sys_init()                        //SYS INIT

{    

    TRISC=0;                            //PORTC is output

    PORTC=0;                            //Clear PORTC

    TRISD=0;                            //PORTD is output

    PORTD=0;                            //Clear PORTD 

}

void uart_init()                        //UART INIT

{

    TXSTA =0x24;                            //TXEN=1,TX enable

                                            //BRGH=1,high speed baud

    RCSTA =0b10010000;                      //SPEN=1,receive enable

                                            //CREN=1

    TRISB=0x00;                             //PORTB is output

    SPBRG=103;                              //SPBRG=FOSC/(16*baud)-1;      (high speed baud)

                                            //     =16000000/(16*9600)-1

                                            //     =104-1=103

    INTCON=0;                               //no interrupt

    PIE1=0;                                 //PIE1 disable

    PIE2=0;                                 //PIE2 disable

    PIR1=0;                                 //Clear PIR1(flag of interrupt) 

    PIR2=0;                                 //Clear PIR2(flag of interrupt)

}

void usart_send_16bits(uint16_t send_data)            //send 2 bytes 

{

     uint16_t send_buffer;                      

      send_buffer=send_data;                            

      usart_send_8bits((uint8_t)(send_buffer>>8));      //send high byte

      usart_send_8bits((uint8_t)(send_data));           //send low  byte

}

void usart_send_8bits(uint8_t send_data)            //send one bytes 

{

      TXREG=(uint8_t)(send_data);                       

      while(TRMT==0);                                 //send is over

}

void TMR1_init()                                    //TMR1 INIT

{

    T1CON=0;                                         //TMR1 is TIMR

    TMR1=(uint16_t)(65535-985);                      //delay is 1000*FOSC=1000*0.25=250us

    TMR1IF=0;                                        //Clear TMR1IF

}

void PWM_init()                                     //PWM INIT

{

    PR2=0xff;                                        //写入PR2寄存器设置PWM周期,PWM周期=[(PR2)+1]*4*TOSC*(TMR2预分频比)

                                                     //                               =[255+1]*4*4/16=256us


    CCPR1L=0;                                       //Clear CCPR1L

T2CON=0x01;

[1] [2]
关键字:PIC16F877A  单片机  PPM调制  激光通信 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic479506.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:PIC单片机ad采样在LCD上显示
下一篇:用PIC18F4520与发电机上的电表实现MUDBUS通信

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

PIC 16f877a PORTB State Change Interrupt仿真与源码
PORT Change Interrupt PIC 16f877A单片机源程序如下:#define      LED_1     PORTd.b0#define      LED_2     PORTd.b1void interrupt(){if(INTCON.RBIF)  {  INTCON.RBIF = 0;  if(!PORTB.B4)   {    LED_1 = 0;    LED_2 = 1;   } 
发表于 2019-11-09
PIC 16f877a PORTB State Change Interrupt仿真与源码
基于pic16f877a的电压输出并显示
;   {                INTF = 0;                  //清除标志        votCounter++;        if(votCounter > 0x0F)  //只有16X2种可能        {         
发表于 2019-11-09
基于pic16f877a的电压输出并显示
PIC16F877A编程PID+PWM+1602液晶显示
;          CHS1=0;  CHS0=0;//系统时钟f/16,选择RA0通道,允许ADC工作  ADON=1;  delay1(); //保证采样延时  ADGO=1; //开启转换过程  while(ADGO); //等待转换完成  resultsc=resultsc+ADRESL+ADRESH*256; //累计转换结果 }resultsc=resultsc/5; //求5次结果的平均值}//PID基准电压采样void jzcy(){resultjz=0;  for(int i=5;i>
发表于 2019-10-24
PIC16F877A单片机led的动态显示
list p=16F877A,R=DECinclude "p16F877A.inc";;;;;user variables;;;;;;;;Count2 equ 23HCount3 equ 24Hdata_out1 equ 25Hdata_out2 equ 26H;;;;;;;reset vector;;;;;;;;;org 0x00goto mainline;;;;;;delay program;;;;;;;delay_2msmovlw 0x05movwf Count2lp0 movlw 0xffmovwf Count3lp1 decfsz Count3,Fgoto lp1decfsz Count2,Fgoto
发表于 2019-10-19
PIC16F877A定时器1实验
PIC16F877A单片机的Timer1是16位的,我们利用此定时器实现一个10ms的定时,在定时中断里我们再判断1s是否到了,到了之后将LED灯状态取反。#include <htc.h> #define u8 unsigned char#define u16 unsigned int __CONFIG(0xFF32); #define LED PORTD char Counter=0; void timer1_init(){ T1CKPS0=1; //1:8 T1CKPS1=1; TMR1CS=0; //定时器模式 TMR1IE=1; TMR1H=0xfb
发表于 2019-01-31
PIC16F877A定时器1实验
小家电热销带动盛群,新唐单片机出货量激增
由于今年白色小家电需求依旧热络,10月开始一波急单带动IC设计盛群(6202)、新唐(4919)MCU出货量增,加上年底耶诞节购物需求,及上半年库存去化告一段落,第四季业绩将优于第三季,全年营运可望倒吃甘蔗。10月相关白牌小家电零组件IC出现节前急单拉货潮,盛群表示,10月开始,已感受到订单回流迹象,客户及终端库存去化、中国双11及年底拉货旺季到来,且中国去美化政策逐季发酵,客户拉货态度转趋积极。上半年受到贸易战影响,客户拉货态度观望,下半年库存水位已降至低点,MCU厂在客户要求下,于10月备妥急单需求,主要以小家电商品IC为主,第四季进入全年出货旺季,法人预估今年第四季MCU厂业绩可望成为全年最高点。
发表于 2019-11-11
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved