问答

汇集网友智慧,解决技术难题

21ic问答首页 - TAG - PIC16F
  • 哪位前辈能告诉我,Pic16f883测电压不准是怎么回事?

    我手头有两只pic16f883,不想报废,于是参考别人代码编写了2路A/D转换程序,采用Proteus仿真误差很大,明明是5V参考电压,结果显示8V多,不知哪里出问题了?时钟从1MHZ~20MHZ都是一样的结果,不知是Proteus仿真软件的bug还是代码有问题,请大侠帮忙// 名称: 数码管显示两路A/D转换结果 //----------------------------------------------------------------- // 说明: 调节RV1和RV2时,两路模拟电压将显示在集成式数码管上. // //----------------------------------------------------------------- #include __CONFIG(0x2004); //?????? //配置字要在头文件后 PROTEUS仿真也要有 改为__CONFIG(0x2002); 也不行 //bit13=1禁止在线调试 bit12=0关系RB3数字口 bit11=0禁止故障保护时钟监视器 bit10 =0禁止内外时钟切换 //bit9/8=00禁止欠压复位 bit7=0使能RAM保护 bit6=0使能ROM bit5=0内部复位RB3为数字引脚 //bit4=0使能上电延时定时器 bit3=0禁止看门狗 bit2:0=100INTOSCO振荡,RA6/7为I/O口 手册14.1配置位 #define INT8U unsigned char #define INT16U unsigned int #define _XTAL_FREQ 4000000UL //共阳数码管0~9的数字段码,最后一位为黑屏 const INT8U SEG_CODE[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF}; //两路模拟转换结果显示缓冲,显示格式为:X.XX X.XX ,第4位和第8位不显示 volatile INT8U Display_Buffer[] = {0,0,0,10,0,0,0,10}; //1.108ms @1MHZ void delay_xms(INT16U ms) { INT8U i; while(ms--) for(i = 0; i < 20; i++); } //----------------------------------------------------------------- // 对通道Channel进行模数转换,转换结果分解存入显示缓冲 //----------------------------------------------------------------- void ADC_Convert(INT8U Channel) { //设置ADCON0寄存器的通道选择位CHS[3..0]=Channel(0~13) //选择通道后等待 CHS3 = Channel >> 3; CHS2 = Channel >> 2; CHS1 = Channel >> 1; CHS0 = Channel >> 0; //__delay_us(1); //选择通道后等待 delay_xms(10); //开始转换--->等待,直到一次转换结束(ADGO还可替换成GO_DONE) //GO_DONE = 1; while(GO_DONE); //ADGO = 1; while(ADGO); //PIC16F877的写法 GODONE = 1;while(GODONE); //读取转换结果,并转换为电压值 //参考电压5v,所以转换结果*500/1023.0,使结果在000~500间 int Result = ( int) ((ADRESL + (ADRESH << 8)) * 500.0 / 1023.0); //AN0的结果放入数组0,1,2单元中,AN1的结果放入数组4,5,6单元中 if (0 == Channel) //通道0的在左面3个数码管显示 { Display_Buffer[0] = Result / 100; Display_Buffer[1] = Result / 10 % 10; Display_Buffer[2] = Result % 10; } else if (1 == Channel) //通道1的在4、5、6数码管显示 { Display_Buffer[4] = Result / 100; Display_Buffer[5] = Result / 10 % 10; Display_Buffer[6] = Result % 10; } } //----------------------------------------------------------------- // 主程序 //----------------------------------------------------------------- void main() { //SCS= 1; //内部时钟,OSCCON配置 手册P64, //0=时钟由配置字1的FOSC2:0决定,1=时钟由IRCF2:0决定 //IRCF2=1;IRCF1=1;IRCF0=0; //内部4MHZ,OSCCON配置 手册P64 //OSTS = 0; //器件依靠内部内部时钟运行,OSCCON配置 手册P64 //1=时钟靠时钟配置字1的FOSC2:0决定,手册P71 TRISB = TRISC = 0x00; //配置数码管输出端口 PORTB = PORTC = 0x00; //以下配置用于TMR0定时器刷新数码管显示 PSA = 0; //前分频给TMR0 PS2 = 0; PS1 = PS0 = 1; //16分频(OPTION低3位为011) TMR0 = (INT8U)(256 - _XTAL_FREQ / 4 / 16 * 0.002); //2ms定时 T0IF = 0; //清TMR0中断标志 T0CS = 0; //TMR0工作于定时器 T0IE = 1; //允许TMR0溢出中断 GIE = 1; //开全局中断 //PEIE = 1; TRISA0 = 1; TRISA1 = 1; //AN0/AN1输入口 ANS0=1; ANS1=1; //AN0/AN1模拟输入 ADCS1 = 1; ADCS0 =0; //设置AD转换时钟为F_OSC/32 VCFG1=0;VCFG0=0; //以电源脚VDD\VSS为参考电压 //VRSS = 0;VROE =0; //VRCON寄存器的bit6/4 手册P98 ADFM = 1; //转换结果右对齐 ADON = 1; //打开A/D转换模块 //__delay_ms(1700); delay_xms(3000); //等待AD模块稳定 while(1) //AN0,1通道开始持续A/D转换 { ADC_Convert(0);delay_xms(10);//__delay_ms(5); ADC_Convert(1);delay_xms(10);//__delay_ms(5); } } //----------------------------------------------------------------- // TMR0定时器溢出中断控制数码管刷新显示两路A/D转换结果 //----------------------------------------------------------------- void interrupt TMR0_ISR(void ) { static INT8U i = 0; if (T0IF&&T0IE) { //PORTB = 0xff; PORTC = 0x00; //暂时关闭位码 PORTB = SEG_CODE[Display_Buffer[i]]; //发送数字段码 PORTC = 1 << i; //发送数码管位码 if(i== 0 || i == 4) RB7 = 0; //点亮小数点 i = (i + 1) & 0x07; //下一位数字索引 TMR0 = (INT8U)(256 - _XTAL_FREQ / 4 / 16 * 0.002);//位间延时间隔2ms T0IF = 0; //清TMR0中断标志 } }

    电压 PIC16F bi go AD NN

    2046浏览量 6回复量 关注量
  • PIC16F1516/7/8/9单片机的开发例程

    哪里可以下载到关于PIC16F1516/7/8/9芯片的相关开发例程?

    芯片 开发 单片机 PIC16F

    1413浏览量 3回复量 关注量
  • LIN的自动波特率问题 sos

    大神们好!按照PIC16F18系列自动波特率的时序,在LIN_RX_IDLE里面,ABD使能,在LIN_RX_SYNC里面,读一次RC1REG将RCIF置0,波特率自动填充SP1BRG里面。现在在LIN_RX_SYNC里面,SPIBRG的值读出是对的,但是程序跳到LIN_RX_PID里面,读出PID报错,数据为0。请大神们指点,谢谢!case LIN_RX_IDLE: if(EUSART1_is_rx_ready() > 0){ //Start Timer LIN_startTimer(READ_TIMEOUT); LIN_rxInProgress = true; LIN_rxState = LIN_RX_BREAK; BAUD1CONbits.ABDEN = 1;//set auto baud detection } break; case LIN_RX_BREAK: if(EUSART1_is_rx_ready() > 0){ if(LIN_breakCheck() == true){ //Read Break LIN_rxState = LIN_RX_SYNC; } else { LIN_rxState = LIN_RX_ERROR; } } break; case LIN_RX_SYNC: if(EUSART1_is_rx_ready() > 0){ while (BAUDCONbits.ABDEN == 1) { if (BAUDCONbits.ABDOVF == 1) { BAUDCONbits.ABDEN = 0; // abort auto baud BAUDCONbits.ABDOVF = 0; // start auto baud BAUDCONbits.ABDEN = 1; // restart auto baud } } index = EUSART1_Read(); RC1REG_DATA=RC1REG; if((SP1BRGL+(SP1BRGH<<8))>0) { LIN_rxState = LIN_RX_PID; }else { LIN_rxState = LIN_RX_ERROR; } } break;

    Microchip PIC16F LIN AB ar ST

    2054浏览量 0回复量 关注量
  • 进不了中断

    为啥我pic16f887电平变化中断进不了中断函数,仿真时候高低电平都有变

    电平 pic pi pic16 PIC16F 中断函数

    1395浏览量 2回复量 关注量