对于下面的问题1,我确实陷入了问题a和b。我真的很困惑如何通过使用<<和>>函数来更改乘法和除法函数以更改引脚/ LED。 任何帮助将非常感激。谢谢!
多个LED以及使用和输入按钮
a。与其使用乘法和除法功能来更改引脚/ LED,不如使用<<和>>功能。参考资料:Deitel和Deitel“ C,如何编程和https://en.wikipedia.org/wiki/Operators_in_C_and_C
b。将程序中的时钟频率更改为1 MHz,并使每个LED的开/关时间为.1秒。这样可以明显提高旋转速度。 (请记住更改_XTAL_FREQ值,因为该值用于XC8内置的__delay_ms()函数)
设备:
低引脚数板(板上的16F1829)和44引脚演示板都在同一块背板上。 (您只能在本实验中使用16F1829。)
带USB电缆的PICKIT 3编程器
MPLAB X(我使用的是v3.00,但实验室计算机上的版本可能不同)
Microchip XC8 C编译器用户手册
PIC16F1829数据表
PICkit 3用户指南
低引脚数板用户指南
“如何编程” Deitel,Pearson / Prentice-Hall(任何版本)
用于研究的Internet浏览器搜索引擎(Google,Bing等) upload_2018-9-5_23-27-22.png
代码在下面。
/*
LEDs on for approximately 0.5 sec.
PIC: 16F1829 Enhanced Mid-Level
Compiler: XC8 v1.34
IDE: MPLABX v3.00 */
#include <pic16f1829.h> //Not required but this is the reference used by "C" for names and location on uC
#include <htc.h> //refers on HiTech C, Microchip purchased HiTech
#define _XTAL_FREQ 4000000 //Used by the XC8 delay_ms(x) macro
#define switch PORTAbits.RA2 // Can use RA2 instead of PORTAbit.RA2 to define pin attached to switch
//instead of saying PORTAbits.RA2 each time
//config bits for the PIC16F1829
#pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=OFF, MCLRE=OFF, CP=OFF, CPD=OFF, BOREN=ON, CLKOUTEN=OFF, IESO=OFF, FCMEN=OFF
#pragma config WRT=OFF, PLLEN=OFF, STVREN=OFF, LVP=OFF
//Initialization subroutine
void initialize(void) {
ANSELC=0; //All pins of Port C are digital I/O
ANSA2=0; //switch pin, RA2, is digital IO
TRISA2 = 1; //switch is an input
TRISC = 0; //all pins of Port C are outputs
OSCCON = 0b01101000; // 4 MHz
}
unsigned char i1; //only need 4 bits to count to 16. unsigned character variable is 8 bits long
// Here is main(). There are many ways to do this 4-pin (LED) sequence
void main(void)
{
initialize();
i1=1; //Start the main program with the variable =1. Could have done this during its definition
while (1) //runs continuously until MCU is shut off
{
if (switch==1) //Button not pressed pin at 5V
{ i1=1; }
while (switch==1) //Button not pressed
{
PORTC=i1; //Note that writing to PORTC writes to LATC
__delay_ms(500);
i1=i1*2;
if (i1==16)
{ i1=1; }
}
if (switch==0) //Button pressed pin at ground
{ i1=8; }
while (switch==0) //Button pressed
{
PORTC=i1;
__delay_ms(500);
i1=i1/2;
if (i1==0)
{ i1=8; }
}
}
}
答案 0 :(得分:1)
a。而不是使用乘法和除法函数进行更改 引脚/ LED,请使用<<和>>功能。参考文献:Deitel和Deitel “ C,如何编程和 https://en.wikipedia.org/wiki/Operators_in_C_and_C
左移value << n
是value乘以2 ^ n或value *(2 ^ n)的整数
右移value >> n
是值除以2 ^ n或value /(2 ^ n))的整数
当您有var
且使用其中一个移位运算符时,您将获取var
的值并将表示其值的二进制数字(位)向左移或正确的。
一个基本的例子:
uint8_t var = 1; //0b00000001 in binary
var <<= 1; //var is now 0b00000010, that is 1*(2^1) or 2
var >>= 1; //var is now 0b00000001, that is 2/(2^1) or 1
使用移位运算符有一个很大的警告,那就是,每当移位位时,都从与移位相反的方向填充0,因此必须注意整数大小。
uint8_t var = 1;
var <<= 4; //var is now 0b00010000, 4 zeros filled in on the right
var = 1;
var <<= 8; //var is now 0b00000000, because 8 zeros were filled in on the right!
现在,关于如何使用它来操纵微控制器上的引脚,您将采用一个递增或递减的变量,并向左或向右移动该变量,并将结果值分配给控制该变量的模块中的寄存器。引脚,在这种情况下为PORTx
模块。在您的代码中,如下所示:
if (switch == 1) //Button not pressed pin at 5V
{
i1 = 0; //initialize to 0
}
while (switch == 1) //Button not pressed
{
PORTC = (1 << i1++); //set will set just one pin at a time, the first will be pin 0, the next pin 1, and so on
__delay_ms(500);
if (i1 == 8){
i1 = 0; //reset variable
}
}
if (switch == 0) //Button pressed pin at ground
{
i1 = 0; //initialize to 0
}
while (switch == 0) //Button pressed
{
PORTC = (0x80 >> i1++); //this will set 1 pin at a time, the first will be pin 7, the next will be pin 6, and so on
__delay_ms(500);
if (i1 == 8)
{
i1 = 0; //reset variable
}
}
b。将程序中的时钟频率更改为1 MHz,并使 每个LED的开/关时间为0.1秒。这应该使旋转 明显更快。 (请记住更改_XTAL_FREQ值,因为这是 用于XC8内置的__delay_ms()函数)
这部分代码:
OSCCON = 0b01101000; // 4 MHz
实际上配置微控制器用于其时钟信号的振荡器的频率。但是,重要的是要知道该时钟信号的来源,根据datasheet,它由配置字1控制。这在代码的#pragma config FOSC=INTOSC
部分中进行设置。
要获得1 MHz,您需要将该行更改为此:
OSCCON = 0b01011000; // 1 MHz
这可以在数据表的OSCCON寄存器说明中找到。
__delay_ms
函数使用_XTAL_FREQ来计算延迟,这就是为什么告诉您更改代码的这一行的原因:
#define _XTAL_FREQ 4000000
对此
#define _XTAL_FREQ 1000000