Multiple LEDs and using and input button

Thread Starter

Wesley Wright

Joined Nov 23, 2016
6
Hello, I am really stuck on part a and b for problem 1 below. I am really confused on how to change the multiply and divide functions to change pins/LED’s, using the << and >> functions instead.
Any help would be much appreciated. Thanks!

Multiple LEDs and using and input button

1. Modify the C program:

a. Instead of using the multiply and divide functions to change pins/LED’s, use the << and >> functions. References: Deitel and Deitel “C, How to Program and https://en.wikipedia.org/wiki/Operators_in_C_and_C

b. Change the clock frequency in the program to 1 MHz and make the on/off time of each LED .1 seconds. This should make the rotation visibly faster. (Remember to change the _XTAL_FREQ value since this is used for the __delay_ms() function built into XC8)

Devices:

Low Pin Count board (16F1829 on board) and 44-Pin Demo Board are both on same backboard. (You only use the 16F1829 for this lab.)

PICKIT 3 programmer with USB cable

MPLAB X (I used v3.00 but a different version may be on lab computers))

Microchip XC8 C Compiler User Manual

PIC16F1829 Data Sheet

PICkit 3 User’s Guide

Low Pin Count Board User Guide

“C How to Program” Deitel, Pearson/Prentice-Hall (Any edition)

Internet Browser Search Engine for research (Google, Bing, etc)
upload_2018-9-5_23-27-22.png
C:
/* 
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;       }
  } 
  }
}
Moderators note : used code tags
 
Last edited by a moderator:

dl324

Joined Mar 30, 2015
16,918
Welcome to AAC!
I am really confused on how to change the multiply and divide functions to change pins/LED’s, using the << and >> functions instead.
It would be helpful if you made it easier for us to help you. Isolate the multiply/divide code and show us your attempt at converting it to shift operations.
 

Thread Starter

Wesley Wright

Joined Nov 23, 2016
6
Here is the multiply code:
i1=i1*2;
Here is the divide code:
i1=i1/2;

completely lost on where to start on changing this to use << and >> functions to change pins/LED’s.
 

Thread Starter

Wesley Wright

Joined Nov 23, 2016
6
I ran into a hint from a question of What do <<3 and >>5 do? I am very new at coding so i was lost by this for a while. However, I came across some good information and think I am starting to understand.

1 << 1 means:

0000000000000001 changes to 0000000000000010
1 << 8 means:

0000000000000001 changes to 0000000100000000
It's a bit shift operation. For every 1 on the right, you can think of yourself as multiplying the value on the left by 2. So, 2 << 1 = 4 and 2 << 2 = 8. This is much more efficient than doing 1 * 2.

Also, you can do 4 >> 1 = 2 (and 5 >> 1 = 2 since you round down) as the inverse operation.
 

Thread Starter

Wesley Wright

Joined Nov 23, 2016
6
I am really new to coding so I was lost by a lot of this. I am still trying to figure out how to incorporate
not sure if this is right. i1=i1*2; would equal i1=i1*4>>1; and would this also be correct? i1=i1/2; would make i1=i1/4>>1
 

dl324

Joined Mar 30, 2015
16,918
I am really new to coding so I was lost by a lot of this.
We're talking about arithmetic, so you can't blame being new to coding for not being able to figure this out.
I am still trying to figure out how to incorporate
not sure if this is right. i1=i1*2; would equal i1=i1*4>>1; and would this also be correct? i1=i1/2; would make i1=i1/4>>1
If a left shift of 1 is equivalent to a multiply by 2, why are you trying to do a multiply by 4 and then a divide by 2?
 

Thread Starter

Wesley Wright

Joined Nov 23, 2016
6
I believe i grasp this now. thanks for being patient with me as learn this.
So i1=i1*2 would then be i1=i1<<1 (the value of i1 would be shifted to the left in the binary code by 1 therefore multiplying it by 2.)
then i1=i1/2 would be i1=i1>>1 (the value of i1 would be shifted to the right in the binary code by 1 therefore dividing it by 2.)
 

dl324

Joined Mar 30, 2015
16,918
I believe i grasp this now. thanks for being patient with me as learn this.
So i1=i1*2 would then be i1=i1<<1 (the value of i1 would be shifted to the left in the binary code by 1 therefore multiplying it by 2.)
then i1=i1/2 would be i1=i1>>1 (the value of i1 would be shifted to the right in the binary code by 1 therefore dividing it by 2.)
Looks like you got it.

Additionally, i1 <<= 1 is equivalent to i1 = i1 << 1. And i1 *= 2 is equivalent to i1 = i1 * 2.

Unix and C appear to have been written for people who couldn't touch type. Less typing means less chance for typos. Particularly when more descriptive variable names are used...
 
Top