We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
This is in connection with my old post http://www.keil.com/forum/20496/
I got great help here. Now I can read serial bit stream into a 32bit long, split it in 4 bytes & after some conversion can send the captured data to my 16*2 LCD. I have done it but some of the input bits were lost while doing it & I got garbage data. The real story is like this:
I want to capture data from a device & display it. The MCU in the device sends the display data to MM5452 LCD controller (www.ti.com/.../snls367b.pdf) which is displayed on 3 1/2 LCD display. I am trying to capture the data from the input pins of the LCD controller which are sent by the MCU in the device.
The LCD controller has 3 input pins. One is DATA ENABLE, another is CLOCK & third one is DATA. DATA is latched on high going CLOCK pulse provided DATA ENABLE is low. The first data bit is start bit which is always 1. Next 35 bits are real data bits out of which first 32 bits are needed. I think last 3 bits are for data format compatibility with other similar controllers.
I inverted the clock pulse & used INT0 to detect it. In the ISR, I read the data bit & saved it in 32bit long. As I got garbage data, I checked the signals on CRO. The clock cycle width was 10uS. I am using 24Mhz crystal on 89S52 so single-cycle instruction will take 0.5uS. That means in my interrupt routine maximum of 20 single-cycle instructions are allowed, which I think it is not possible (at least for me). Because I will need to keep track of START BIT, DATA ENABLE & number of bits collected so as to differentiate the data chunk. Further conversion can be done out of the ISR.
Is it possible to solve this issue on different micro-controller such as AVR or ARM?
Sorry for long post, but I thought I should give you as much information as possible in the first go.
1) Why new thread?
2) Have you considered if there are any microcontrollers available that either supports 32-bit SPI mode, or if it's possible to use a SPI controller in 8-bit or 16-bit mode?
The SPI peripherial is hardware-accelerated to send or receive synchronous serial data with separate clock and data signals... Suddenly, you can get an interrupt when you have a word ready instead of for every clock bit.
Thanks, I have started new post just because my previous problem of collecting data bits is solved.
I have not used SPI yet. Can I get interrupt on specified bits collected, because on observing waveform on scope I found that the LCD controller gets 48 bits in one DATA ENABLE signal. Out of which 32 bits starting from second (1st is Start Bit) are used as data.
For now, I am planning to use external shift registers to collect the data & then my MCU will get data from it.
Do start to read up on SPI.
If you read in 6 bytes with SPI, i't easy to figure out what bytes you are not interested in.
The big question you should ask is: Is it likely that the LCD manufacturer expected users to use external shift registers or play with interrupts every 20us? Or is it likely that they implemented a standard SPI interface for efficient compatibility with a large percentage of microcontrollers?
What does the application notes suggests? External shift registers? Or connecting directly to pins on microcontoller?
Trying to implement a SPI slave in software is extremely hard, because of the timing. Trying to implmenet a SPI master is trivial.
You need to listen, so you need to be the SPI slave. Have you made sure that you got a processor with SPI support? Because that is explicitly the problem you want to solve - how to be the receiving end of SPI communication.
And it's a bit silly to design in discrete hardware an SPI device when SPI is directly available in so many processors.
Ok, I will study the SPI interface already available in microcontrollers.
The LCD controller will not care about the source of the signals whether they are from shift register or microcontroller as long as the data timing requirements are met.
The shift register/s I use will not interfere the internal MCU & LCD controller communication. The signals sent by the internal CPU to the LCD controller will also be fed into my shift register. My mcu will read the shift register whenever the Data Enable signal is disabled(high). I am pretty sure that I can do it.
Apart from SPI interface, I am also interested in using ARM for this application. I learnt somewhere that a 2MHz ARM is same powerful as 20MHz C51. Is it true. If yes, ARM can solve my problem without using external hardware.
I have an ARM development board namely BlueBoard LPC2148. But I have not used it, in fact I have no experience/knowledge of using ARM processors.
But the SPI is a peripherial device built specifically around a shift register.
So many microcontrollers specifically have a 8-bit or wider shift register integrated, complete with pins for data and clock, and with logic to generate an interrupt when n bits have been sent or received.
Some of the SPI implementations are a bit more advanced than others. Some can only recive n*8 bits. Some can be configured to transfer words of n bits. Some have ddouble-buffering. Some have FIFO. Some even support DMA transfers.
But in the end - they are specifically designed for synchronous serial receive/transmit of data.
Per Westermark, thank you for your reply.
I will have a look towards using SPI in microcontrollers. I will continue my project using external shift registers. After getting proper results by this method I will consider SPI in my final design.
Sorry for posting too late. Actually I was trying to correct some problems in my old ISP programmer by Atmel(schematics as in isp_c_v5 & AT89ISP software). Still it is not working satisfactory, sometimes it works sometimes not. This programmer has support for AT89S8253 which I want to use now(for SPI feature).
ONE GOOD NEWS IS THAT I HAVE SUCCEEDED IN CAPTURING THE CORRECT DATA BY USING EXTERNAL SHIFT REGISTERS.
Per Westermark, as per your suggestion now I am trying to capture the same data using SPI port of AT89S8253. I have not used the SPI port before. I have changed the code which was originally written for 89S52.
In the initialization I added following.
P1 = 0xFF; //P1.4-P1.7 should be high before SPI is enabled SPCR |= 0x40; //Set SPE bit to enable SPI (6th bit) SPCR &= 0xEF; //clear MSTR bit (4th bit) SPCR |= 0x80; //Set SPIE bit to enable SPI interrupt(7th bit) // SPCR = 0xC0; //equivalent to above commands??? ES = 1; //enable serial interrupt, as it is shared by SPI EA = 1; // Enable Global Interrupt Flag
In the serial ISR I wrote
void com_isr (void) interrupt 4 { /*------------------------------------------------ Received data interrupt. ------------------------------------------------*/ if (RI != 0) { RI = 0; } /*------------------------------------------------ Transmitted data interrupt. ------------------------------------------------*/ if (TI != 0) { TI = 0; } if ((SPSR & 0x80) !=0 ) //if SPIF bit is set { debug_led2=!debug_led2; SPSR &= 0x7F; //clear SPIF bit serial_data=SPDR; // read receive data } }
The problem is that, though a number of bytes should be received, the debug LED is toggled only once. Can you please help?
I have wired /DataEnable to SS pin, Clock to SCK pin & Data to MOSI pin.