Hi;
I need to send data serially to one GPIO pin to 595 Shift register, I dont want to use SPI. i had written small program to check it with simulator but keil shows error . please check what it is and guide me
#include<LPC21xx.h>
#define Data_Pin (1 << 21) #define Data_DIR_SET (IO0DIR |= Data_Pin)
#define Clock (1 << 22) #define Clock_DIR_SET (IO0DIR |= Clock) #define Clock_SET (IO0SET = Clock) #define Clock_CLR (IO0CLR = Clock)
#define Latch (1 << 23) #define Latch_DIR_SET (IO0DIR |= Latch) #define Latch_SET (IO0SET = Latch) #define Latch_CLR (IO0CLR = Latch)
int buff[]={0x00,0xff,0xfd};
void shift_595(int buff) { Clock_CLR; Latch_CLR; Data=buff; Clock_SET; Clock_CLR; } int main(void) { int loop; while(1){ for(loop=0;loop<8;loop++){ shift_595(buff[loop]); } Latch_SET; } }
You didn't tag anything as code, so it is too hard to read.
But several comments.
You complain about an error - so why didn't you post the error message?
You have written "#define Clock_SET (IO0SET = Clock)" Note that the parentheses isn't really too valuable there. It still isn't an isolated and "normalized" statement requiring the normal semicolon.
If the compiler supports inline functions, it may be better to implment the action as an inline function:
__inline void Clock_Set() { IO0SET = Clock; }
When not using inline, but "hiding" statements in a #define, it is often good to write:
#define MyAction(param) \ do { \ IO0SET = Clock; \ } while (0)
Another thing is that you don't consider timing. You have:
Clock_SET; Clock_CLR;
What happens if you have a 72MHz processor where each clock cycle is 14ns long? What is the minimum pulse time the shift register needs? Remember that you also need to consider the rise and fall times, which depends on the amount of capacitances.
Sorry for not posting error message.
Error message "main.c(21): error: #137: expression must be a modifiable lvalue" and error is pointed to Data=buff;
i am new to embedded, just now learning things. anyway thanks for giving valuable suggestion . As per my assumption. the data is hexadecimal value and the GPIO pin can only be 0 or 1. so how can i send data serially using single pin. I think i made some error in assigning. can you correct me.
You haven't shown us what Data is, but
Data=buff;
buff is an array. So when you assign buff, you assign a pointer. And the compiler complains that Data isn't a pointer so can't accept the assign.
This has nothing at all with embedded programming to do.
About sending out a number serially on a pin:
#define NELEM(a) (sizeof(a) / sizeof(*(a))) unsigned byte_idx; unsigned char data_to_send[] = {0x15,0x17,0xff,0x13}; unsigned char to_send; for (byte_idx = 0; byte_idx < NELEM(data_to_send); byte_idx++) { to_send = data_to_send[byte_idx]; for (i = 0; i < 16; i++) { if (to_send & 1) { IO0SET = DATA_PIN; } else { IO0CLR = DATA_PIN; } to_send >>= 1; // optional extra delay to make the pin stabilize (setup time) IO0SET = CLOCK_PIN; // need delay here to give suitably long clock pulse IO0CLR = CLOCK_PIN; // need delay here to make sure clock is deasserted long enough before next bit. } }
Actual positions to delay can be moved up or down a bit depending on optimization. Best is to do the output in assembler since that makes sure you are in control of the clock cycles consumed. But most embedded compilers supports some form of nop() or _nop() or __nop() or similar intrinsic that gives one instruction cycle delay.
Note that the code may need to emit the data in reverse order, i.e. most significant instead. Then test most significant bit instead of least significant. And shift in reverse direction.