A. PIC16F887单片机如何使用内部振荡器作为系统时钟源
PIC16F877好像没有内部震荡源,需要外界电阻电容或晶体.因为很长时间不玩PIC的芯片了,有点忘了.说的不对请谅解.
B. 晶振20MHZ,用C语言编写一个延时5ms的函数
如果用软件延时,你可以用示波器测试,修改参数,直到调准为止。
C. 高手你好,单片机PIC16F887与PIC16F877A主要有什么区别编程时要注意哪些
主要区别,887是纳瓦系列,功耗比877或877a要低;
887有内部RC振荡器,887/887A没有内部振荡器;
887有一个普通CCP模块,一个增强型CCP模块,877A只有两个普通的CCP模块;
887有十四个10位AD输入通道,877只有八个10位AD输入通道
887可以使用内部复位电路(RE3可以做IO或者做复位引脚),877A无此功能;
还有其他的东西,在实际的使用中,你要对着DATASHEET来看(特别是IO口的使用,不同的型号IO口内部结构都可能不太一样,认真看datasheet),887有中文的datasheet,去这里下载chinese版本的: http://ww1.microchip.com/downloads/en/DeviceDoc/41291e_cn.pdf
877A没有中文版,如果用到那就自己慢慢看英文的: http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf
另外,我很少用PROTEUS(上大学时候用过),现在我基本上是用实际芯片来做硬件仿真。没法回答你的PROTEUS问题。但我可以告诉你的是,Mplab IDE里的debuger选项中有Proteus VSM。你可以在Proteus软件里先画好图,然后保存关闭。然后在MPLAB里打开你的程序项目,然后打开Debugger -> Select Tools -> Proteus VSM,然后在弹出的PROTEUS窗口打开你刚画的PROTEUS文件,就可以在MPLAB里直接调用Proteus来仿真程序了。 这样可以直接单步调试程序,可以让你直观看到每一条指令对单片机和电路的改变。
D. PIC16f887 点亮LED 问题
__CONFIG(FOSC_INTRC_NOCLKOUT & WDTE_OFF & PWRTE_ON& CP_OFF& BOREN_OFF& MCLRE_ON&IESO_OFF& FCMEN_OFF&LVP_OFF );
这样试一下看
E. 谁有用pic单片机16f877实现产生随机数的c语言程序和仿真图
这个简单,你开一个定时器,然后随机读取定时器内的值,该值就是随机数了。当然,这个是伪随机数。
F. 单片机C语言
#include <intrins.h>
c51中的intrins.h库函数
_crol_ 字符循环左移
_cror_ 字符循环右移
_irol_ 整数循环左移
_iror_ 整数循环右移
_lrol_ 长整数循环左移
_lror_ 长整数循环右移
_nop_ 空操作8051 NOP 指令
_testbit_ 测试并清零位8051 JBC 指令
详解:
函数名: _crol_,_irol_,_lrol_
原 型: unsigned char _crol_(unsigned char val,unsigned char n);
unsigned int _irol_(unsigned int val,unsigned char n);
unsigned int _lrol_(unsigned int val,unsigned char n);
功 能:_crol_,_irol_,_lrol_以位形式将val 左移n 位,该函数与8051“RLA”指令
相关,上面几个函数不同于参数类型。
例:
#include
main()
{
unsigned int y;
C-5 1 程序设计 37
y=0x00ff;
y=_irol_(y,4); /*y=0x0ff0*/
}
函数名: _cror_,_iror_,_lror_
原 型: unsigned char _cror_(unsigned char val,unsigned char n);
unsigned int _iror_(unsigned int val,unsigned char n);
unsigned int _lror_(unsigned int val,unsigned char n);
功 能:_cror_,_iror_,_lror_以位形式将val 右移n 位,该函数与8051“RRA”指令
相关,上面几个函数不同于参数类型。
例:
#include
main()
{
unsigned int y;
y=0x0ff00;
y=_iror_(y,4); /*y=0x0ff0*/
}
函数名: _nop_
原 型: void _nop_(void);
功 能:_nop_产生一个NOP 指令,该函数可用作C 程序的时间比较。C51 编译器在_nop_
函数工作期间不产生函数调用,即在程序中直接执行了NOP 指令。
例:
P()=1;
_nop_();
P()=0;
函数名: _testbit_
原 型:bit _testbit_(bit x);
功 能:_testbit_产生一个JBC 指令,该函数测试一个位,当置位时返回1,否则返回0。
如果该位置为1,则将该位复位为0。8051 的JBC 指令即用作此目的。
_testbit_只能用于可直接寻址的位;在表达式中使用是不允许的。
G. 绘制一单片机最小系统电路图,编写程序控制P1.7口输出低电平,并点亮发光二极管。求大神解答哇😭
编程实现对 8 个 LED 的输出控制 将实验箱中的 8255 片选信号连接到 218H~21FH,将 8255 的 4 个寄存器地址(A、B、 C 端口及控制字寄存器端口)设置为 218H~21BH。将 8255 的端口 A 的 8 个引脚:PA0~PA7 与 8 个 LED 对应相连,然后打开实验箱电源,最后编程对 8 个 LED 进行显示控制。
程序清单:
CODE SEGMENT
ASSUME CS:CODE
START: MOV DX,21BH
MOV AL,80H
OUT DX,AL ;工作方式初始化
MOV DX,218H
MOV AL,0FEH ;设置输出数据,即显示模式
MOV CX,80 ;设置循环次数
LN: OUT DX,AL
ROL AL,1
CALL DELAY ;调用延迟程序
LOOP LN
MOV AH,4CH
INT 21H ;返回 dos
DELAY PROC ;延迟子程序
PUSH CX
MOV BX,2000
A0: MOV CX,3000
A1: LOOP A1
DEC BX
JNZ A0
POP CX
RET DELAY
ENDP
CODE ENDS
END START。吴鉴鹰单片机开发板。
从刚开始接触单片机,到现在已经有4年的时间了,在这期间学习和使用了51单片机、飞思卡尔单片机,LPC2138,PIC16F887等系列的单片机,每接触一款单片机,都会经历熟悉其基本开发,然后将其用于项目中的过程,对于如何学习一款单片机,自己做了如下的总结。
大家都知道,51单片机是最容易入门的,不仅因为其编程简单,更重要的是网上的资料非常丰富。所以一般学习单片机开发的都将51单片机作为入门开发的首选。我学习51单片机的时候是采用这样的一个步骤进行学习的:
第一步(熟悉的过程):买了一款51单片机开发板,然后就开始了我的学习之旅,刚开始的时候没有去看视频教程,而是对着一本实验教材进行学习,那本实验教材的名字记不清楚了,但是其内容就是围绕单片机的LED灯进行控制,将51单片机内部的各个功能部件全部都使用到了,这样就能使我在很短的时间内,通过控制LED灯的亮、灭熟悉了51单片机的内部的各种资源,这时对51单片机也就没有感到陌生了。所以,个人觉得,学习单片机,要从实验入手,先熟悉单片机再说,开发语言开始使用的是C语言。
第二步(进阶的过程):有了第一步的基础之后,接下来的便是进阶的过程,当时,我看的是郭天祥十天学会单片机的视频教程,因为这个教程从基础到复杂的编程慢慢深入,讲的比较的全面,而且也生动,所以那一阶段,也是我学习单片机进步最快的阶段,每次听课的时候,按照上面的实验,以及课堂上面调试程序时出现的一些问题,自己认真的在电脑上进行调试,并分析产生故障的原因,让我有了一定的开发基础。在看完了视频教程之后,后面又对基础的知识进行了下补习,主要是看单片机原理性的教材,因为有些细节性的东西还是要从教材上面获得。
H. 单片机控制红外程序
给你一个PIC写的接收红外遥控器的程序。
//******************************************************
//mcu: PIC16F883
//author:
//data:
//ver: 1.0
//********************************************************
#include <pic.h>
#include <pic16f887.h>
#include "main.h"
// 函数声明部份
void interrupt IRQ_TEST(void);
void fun_intset(void);
void set_port(void);
void fun_timerset(void);
void delay_10us(void);
void delay_130us(void);
void test_remote(void);
// 主函数
void main()
{
set_port();
fun_timerset();
fun_intset();
delay_10ms();
ram_ini();
GIE=1;
while(1)
{
asm("clrwd");
test_remote();
}
}
//端口I/O定义子程序
void set_port()
{
ANSEL =0X00; //porta io port
ANSELH=0X00; //portb io port
//TRISX BIT=1, PORTX AS INPUT
TRISA = 0x0F; //RA0-RA3 INPUT ,RA4-RA5 OUTPUT
TRISB = 0x07; //RB0 PASS0, RB1-RB2 INPUT ,RB3-RB6 OUTPUT
TRISC = 0x0F;
// TRISC = 0x03; //RC0-RC1 INPUT,RC5-RC6 OUTPUT , RC3 RC4 EEPROM SCL SDA
PORTC=0;
PORTA=0XFF;
// WPUB=0XFF;
PORTB=0X07;
}
//中断子程序
void interrupt IRQ_TEST(void)
{
if(T0IF) //Timer0中断服务子程序
{
TMR0=0xce;
T0IF=0;
timer_100us++; //100us
}
if(INTF==1)
{
INTF=0;
timer_rec=timer_100us;
timer_100us=0;
flag_rec_remote=1;
}
}
//定时器0初始化设置子程序
void fun_timerset()
{
//Timer0初始化设置
PSA=0;//Timer0 使用预分频器
//Timer0选择分频率为1:2
PS0=0;PS1=0;PS2=0;
//内部时钟定时方式,定时时间:200uS,误差:0uS
T0CS=0;
// TMR0=0x9b;
TMR0=0xce; //100us
}
/*
//定时器2初始化设置子程序
void fun_timer2set()
{
//Timer2初始化设置
//timer2使用预分频率1:1
T2CKPS0=0;T2CKPS1=0;
//timer2使用后分频率1:1
TOUTPS0=0;
TOUTPS1=0;
TOUTPS2=0;
TOUTPS3=0;
//定时器2定时时间为:200uS,误差:0uS
TMR2=0x38;
TMR2ON=1;
}
*/
//中断允许设置子程序
void fun_intset()
{
T0IE=1;//Tiemr0中断允许
INTEDG=0; //RB0 FALLAGE INTERRUPT
INTE=1;
INTF=0;
}
void ram_ini(void)
{
}
//------------------------------------------------------------
//*****************************************************************************
void delay_10us(void)
{
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
}
void delay_130us(void)
{
uchar i;
for(i=0;i<13;i++)
{
NOP;
NOP;
NOP;
}
}
void delay_10ms(void)
{
unsigned int i;
for(i=0;i<1000;i++)
{
NOP;
NOP;
NOP;
NOP;
NOP;
}
}
void test_remote(void)
{
uchar rec_ok,i;
if(flag_rec_remote==1)
{
flag_rec_remote=0;
// remote_buf[rec_byte]=timer_rec; //test use
// rec_byte++; //test use
// return; //test use
if(flag_rec_head==0)
{
if(timer_rec>=90&&timer_rec<=140) //135
{
flag_rec_head=1;
rec_byte=0;
rec_bit=0;
rec_buf=0;
return;
}
}
else
{
if(timer_rec>=8&&timer_rec<=12) //11.2
{
rec_buf=(rec_buf>>1);
rec_buf=rec_buf&0x7f;
}
else if(timer_rec>=18&&timer_rec<=22) //22
{
rec_buf=(rec_buf>>1);
rec_buf=rec_buf|0x80;
}
else if(timer_rec>=90&&timer_rec<=140)
{
flag_rec_head=1;
rec_byte=0;
rec_bit=0;
rec_buf=0;
return;
}
else
{
flag_rec_head=0;
rec_byte=0;
rec_bit=0;
rec_buf=0;
return;
}
}
if(flag_rec_head==1)
{
rec_bit++;
if(rec_bit==8)
{
remote_buf[rec_byte]=rec_buf;
rec_byte++;
rec_bit=0;
if(rec_byte==4)
{
NOP;
NOP;
NOP;
NOP;
rec_byte=0;
rec_bit=0;
rec_buf=0;
flag_rec_head=0;
}
}
}
}
}
I. PIC16F877A单片机,晶振是4M(内部的晶振),怎么用C语言实现1us的延时
是ms吧,我用过的都是ms,基本上不用us
delay1ms(uchar T) //单位时间Tms延时,即T是多少,就延时多少ms
{
uchar time;
while(T--)
for(time=0;time<89;time++);
}
这个我用MPLAB的秒表测过,是1ms,差一点点,T越大越准确,不过要注意变量类型
还有这个也行
delay1ms(uchar T) //单位时间Tms延时
{
uchar time;
while(T--)
for(time=0;time<89;time++);
}
J. keil中的16F887在哪
keil只支持编译8051内核的单片机,16f887是pic单片机。
你要编译pic16f887需要去microchip官网下载mplab编译器。
如还有问题,欢迎追问