I'm learning PIC (pic18f4550) and pretty new to microcontroller programming. I'm trying get value of three button on PORTA and send it to a 8×8 led matrix as X coordinates through a 74LS595. The problem is that the value go to the led matrix doesnt change when i pressed the buttons to create different value. I'm simulating on Proteus so I guess I don't need debounce function. Here's my code and schematic:
#include<p18f4550.h>
#define SCK LATBbits.LATB0
#define DATA PORTBbits.RB1
#define SCL PORTBbits.RB2
void Data_in(unsigned char k){
DATA=k;
SCK=0;
SCK=1;
}
void LatchData(){
SCL=0;
SCL=1;
}
void Send1byte(unsigned char data)
{
unsigned char i,temp;
for(i=0;i<8;i++)
{
temp = data & (1<<i);
if(temp)
{
DATA = 1;
}
else
{
DATA = 0;
}
SCK = 0;
SCK = 1;
}
SCL = 0;
SCL = 1;
}
unsigned char getMatrixX(unsigned char in_X)
{
switch(in_X)
{
case 0: // the value stuck here
return 0b01111111;
case 1:
return 0b10111111;
case 2:
return 0b11011111;
case 3:
return 0b11101111;
case 4:
return 0b11110111;
case 5:
return 0b11111011;
case 6:
return 0b11111101;
case 7:
return 0b11111110;
default:
return 0b11111111;
}
}
void main()
{
TRISA = 1;
TRISC = 1;
TRISB = 0;
TRISD = 0;
PORTD = 0x80;
while(1){
Send1byte(getMatrixX(LATA));
}
}
This is link to my schematic: my Schematic
Really appreciate any solutions and advices. Sorry for my bad english.
Best Answer
There are a number of things that need fixing in your code before we can start to assist with the functional problems. I have listed a few below.
Use of TRIS
Please see the answer from Handoko, which deals with this.
Use of LAT vs. PORT registers
You call your function like this:
Send1byte(getMatrixX(LATA))
. I assume your intention is to get the current status of the input buttons and send them to this function.This will not work, you need to read from the PORTA register instead. The correct code would read
Send1byte(getMatrixX(PORTA))
.Why is this? There is a short explanation in the datasheet:
And a helpful image:
The internal data line which is used when you read the PORT bit (bottom left, from the green block) is connected to the input buffer, which comes directly from the I/O pin. In contrast the data line used when you read the LAT bit (top left, connected to the red block) only reads the status of the data latch. It is not connected to the input.
Note that the SCK/DATA/SCL definitions should work (writing to the PORT bit will set the LATch) but I usually keep all writes to the LATch except where impossible (e.g. bidirectional busses).
Configuration of analogue functions
You need to disable the analogue functions which are multiplexed onto PORTA pins. See this note from the datasheet:
In addition the comparator function also needs to be disabled. To set all PORTA pins to digital inputs, see Register 21-2 (ADCON1) in the datasheet. You might try:
If you don't do this then you will never get the input data from your switches, unless the Proteus simulator does unusual things.
Simplifying getMatrixX()
You could simplify your getMatrixX() function in a number of ways, depending if you care about code or data space. Here's one which uses a table lookup (untested):
It would be simple to do the same thing with a shift and some logic, avoiding the lookup table: