Несколько светодиодов и кнопки использования и ввода - PullRequest
0 голосов
/ 06 сентября 2018

Я действительно застрял в части a и b для задачи 1 ниже. Я действительно запутался в том, как изменить функции умножения и деления для изменения выводов / светодиодов, используя вместо этого функции << и >>. Любая помощь приветствуется. Спасибо!

Несколько светодиодов и кнопка использования и ввода

  1. Изменить программу C:

а. Вместо использования функций умножения и деления для изменения выводов / светодиодов используйте функции << и >>. Ссылки: Deitel и Deitel «C, как программировать и https://en.wikipedia.org/wiki/Operators_in_C_and_C

б. Измените тактовую частоту в программе на 1 МГц и установите время включения / выключения каждого светодиода на 0,1 секунды. Это должно сделать вращение заметно быстрее. (Не забудьте изменить значение _XTAL_FREQ, поскольку оно используется для функции __delay_ms (), встроенной в XC8)

Устройства:

Плата с низким количеством выводов (16F1829 на плате) и демонстрационная плата с 44 выводами находятся на одной задней панели. (Вы используете только 16F1829 для этой лаборатории.)

PICKIT 3 программатор с USB-кабелем

MPLAB X (я использовал v3.00, но на лабораторных компьютерах может быть другая версия))

Руководство пользователя компилятора Microchip XC8 C

PIC16F1829 Лист данных

PICkit 3 Руководство пользователя

Руководство пользователя платы с низким числом выводов

«Как программировать» Дейтель, Пирсон / Прентис-Холл (Любое издание)

поисковая система интернет-браузера для исследований (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; }
        }
    }
}  

1 Ответ

0 голосов
/ 06 сентября 2018

а. Вместо использования функций умножения и деления для изменения контакты / светодиоды, используйте функции << и >>. Рекомендации: Deitel и Deitel «C, как программировать и https://en.wikipedia.org/wiki/Operators_in_C_and_C

Сдвиг влево value << n - это целочисленное умножение значения на 2 ^ n или значения * (2 ^ n)

Сдвиг вправо value >> n - целочисленное деление значения на 2 ^ n или значение / (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
        }

    }

б. Измените тактовую частоту в программе на 1 МГц и сделайте Время включения / выключения каждого светодиода .1 сек. Это должно сделать вращение заметно быстрее (Не забудьте изменить значение _XTAL_FREQ, так как это используется для функции __delay_ms (), встроенной в XC8)

Эта часть вашего кода:

OSCCON = 0b01101000; // 4 MHz

Фактически настраивает частоту генератора, используемого микроконтроллером для его тактового сигнала. Однако вам важно знать источник этого тактового сигнала, который в соответствии с таблицей 1034 * управляется словом конфигурации 1. Это установлено в части #pragma config FOSC=INTOSC вашего кода.

Чтобы получить 1 МГц, вам нужно изменить эту строку на:

OSCCON = 0b01011000; // 1 MHz

Это можно найти в описании регистра OSCCON в таблице.

Функция __delay_ms использует _XTAL_FREQ для вычисления задержки, поэтому вам предлагается изменить эту строку вашего кода:

#define _XTAL_FREQ 4000000

К этому

#define _XTAL_FREQ 1000000
...