looking help on 8051 timer interrupt and switch input

JohnInTX

Joined Jun 26, 2012
4,787
As @cmartinez says, you are doing fine and you have progressed a lot. Sometimes, I misunderstand your actions forgetting that some of the problem is in the language barrier and misunderstanding of terms. I will try to remember that. When I first studied this stuff, there was a language barrier for me too - and those books were written in my native English!

Keep progressing doing a bit at a time and resolving all questions in the design and bugs in the code before moving on. That builds a good foundation for future work.

One good thing about flow charts is that the flow reads the same in any language and you don't need to know anything about computer programming to solve problems with them.
 

JohnInTX

Joined Jun 26, 2012
4,787
Do you fully understand ACK and NAK?

When writing to the slave, the master writes 8 bits of data then sends one more clock (9 total) to get an ACK or NAK from the slave. To do this the master:
1) sets SDA to an input
2) sets SCL=1
3) reads SDA
4) sets SCL=0
If SDA was 0, the slave ACKnowledged and the master can send another byte.
If SDA was 1, the slave NAKed (negative acknowledged) the byte. The master must stop sending data and send a stoP condition

See the quote in #195. Your I2C_Send() routine does this at the lines noted. It returns the value of SDA on the 9th clock. If 0 you can continue. If 1 you have to stop. Something like this:
C:
unsigned int Read_DS1307(void){
  if(I2C_Send(slave_address_write) == 1){  // send slave address + WRITE
     // the slave NAK'ed  stop the transaction...
    I2C_Stop();
    return FALSE;
  }

  if(I2C_Send(register_address) == 1){ // send register address
     // the slave NAK'ed  stop the transaction...
    I2C_Stop();
    return FALSE;
  }

  I2C_Restart()  // no errors so far, send rS

if(I2C_Send(slave_address_read) == 1){  // send slave address + READ
     // the slave NAK'ed  stop the transaction...
    I2C_Stop();
    return FALSE;
  }
  // read loop here.

  return TRUE;  // array is filled with valid data
}
Note that when writing, the slave generates the ACK/NAK. When reading, the master generates ACK or NAK. But in both cases, the master is the one generating the SCL clock.

There are other ways to do it but the important thing is to detect NAK, end the transaction, issue I2C stoP condition and exit with some error that indicates that the data you wanted is not available.
 
Last edited:

Thread Starter

Parth786

Joined Jun 19, 2017
642
I compiled program and I am getting errors. whats wrong
C:
#include<reg51.h>
sbit SDA = P0^0;
sbit SCL = P0^1;

#define SDA_Low      (0)
#define SDA_High     (1)
#define SCL_Low      (0)
#define SCL_High     (1)
#define False            (0)
#define True             (1)
#define ack_bit         (1)

#define slave_address_write  (0xD0)
#define register_address  (0x00)
#define slave_address_read  (0xD0)

//Set initial values of SCK and SDA pins //   
 void I2C_Inlization(void)   
  {
          SDA = SDA_High;
          SCL = SCL_High;
  }

//I2C_Start sends start bit sequence//   
  void I2C_Start(void)
  {
          SDA = SDA_Low;
          SCL = SCL_Low;
  }

// I2C_ReStart sends start bit sequence   
 void I2C_Restart(void)
  {
         SDA = SDA_High;
         SCL = SCL_High;
         SDA = SDA_Low;
         SCL = SCL_Low;
  }

//I2C_Stop sends stop bit sequence//   
  void I2C_Stop()
  {
        SCL = SCL_Low;
        SDA = SDA_Low;
         SCL = SCL_High;
         SDA = SDA_High;
  }
//I2C_Send_ACK sends ACK bit sequence
  void I2C_Ack()
  {
         SDA = SDA_Low;
         SCL = SCL_High;
         SCL = SCL_Low;
         SDA = SDA_High;
  }

//I2C_Send_NACK sends NACK bit sequence //   
  void I2C_Nak()
  {
        SDA = SDA_High;
        SCL = SDA_High;
        SCL = SCL_Low;
       SDA = SDA_High;
  }
   
 unsigned char I2C_Send(unsigned char Data)
  {
       unsigned char i;
       unsigned char   ack_bit;
      for (i = 0; i < 8; i++)
     {
     if ((Data & 0x80) == 0)
          SDA = SDA_Low;
          else
          SDA = SDA_High;
          SCL = SCL_High;
          SCL = SCL_Low;
          Data<<=1;
  }
          SDA = SDA_High;
         SCL = SCL_High;
         ack_bit = SDA;
         SCL = SCL_Low;
         return ack_bit;
  }
   
     
unsigned int Read_DS1307(void){
  if(I2C_Send(slave_address_write) == 1)  // send slave address + WRITE //
     {  
         I2C_Stop();
         return False;
  }
  if(I2C_Send(register_address) == 1)  // send register address
     {   
       I2C_Stop();
       return False;
  }
     I2C_Restart();  // no errors so far, send rS
  if(I2C_Send(slave_address_read) == 1)  // send slave address + READ
   {  
      I2C_Stop();
      return ack_bit;
  }
  return True;  // array is filled with valid data
}
Errors
compiling i2c.c...
i2c.c(69): error C141: syntax error near '1'
i2c.c(69): error C141: syntax error near ')'
i2c.c - 2 Error(s), 0 Warning(s).
 

spinnaker

Joined Oct 29, 2009
7,830
ack_bit is defined above as (1)

Line 69 evaluates as
unsigned char ack_bit (1);

Actually the line is evaluating as

unsigned char (1);

No idea what the TS is trying to do that.

I don't understand any of the defines. For example

#define SDA_Low (0)

What is with the ()s? Syntax wise perfectly valid but what is the purpose of the parenthesis marks? Totally unneeded and all it does is it makes for confusion.

Someone at the TS's level should not be using macros anyway. They can get too tricky to track down errors. Exactly like in this case.
 

JohnInTX

Joined Jun 26, 2012
4,787
Oops! You are absolutely correct. I missed the line number of the error, too. That's what I get for committing the sin of posting before coffee!
Thanks.

As for the parenthesis around the defined values, it is of course not necessary here. Sometimes its a good idea when the #define is an expression to ensure that unexpected associations or operator precedence issues when the macro is used in other expressions.

I don't know why TS is using them in this case. There are lots of extra brackets too but one thing at a time.
 

Brian Griffin

Joined May 17, 2013
64
TS needs to pick up a book or attend a class in C. TS has another thread that is now over 100 posts. A forum is a fine place to get tips or work through an issue or two but no place to learn something as complex as C from the ground up.
Agreed at that. However, this depends on the individual.

C or C++ must be learned using the computer first. Know how the syntax in these languages work and practise with simpler programs. Example writing a small menu in the command prompt, or play around with the flow of the code.

I had no class taken when I started C++ as a teenager. Back then where all was a shaky dial-up connection, it was very hard to ask online. I had to make do with sitting in the bookstores and secretly reading the expensive programming guides (sometimes the staff would reprimand and had to obey or else I would be ejected). I took notes of important code fragments on a piece of paper and improvised it.

However, I got stuck at pointers due to the lack of knowledge of assembly and computer architecture. I do believe some guys like you grew up with assembly language first before more of the High-Level language were invented, so pointers are easier on some people, but not me. I stopped learning those languages (I learned them on and off due to the rigid expectations of tiger parents) until I exited high school and then when I entered college, I got to revisit the topics again. This time around, it was a hell lot more easier.

The time when I got my Pickit2 and the starter kit for my birthday present in the end of my second year, I messed around with their limited Microchip tutorial booklets which were included in the CD. I learned to write assembly and more assembly - like how to make a delay goes longer (all the funny decfsz thing), or try to invoke an interrupt and make toys and decorations. When I took the Microcontroller class, the book I got was the Mazidi one. It was extremely informative and I did try many examples inside like the LCD program, and all of them work. At the end, all that, I whipped a very limited Christmas toy based on Myke Predko's book in the bookshop (again, I couldn't afford his book :p because I had to save up for that iPod [I was quite that kid back then]). It managed to squeeze out that "Merry Christmas" or the "Santa claus is coming back to town" song, but with a chime effect. I think I stored the photo or that toy but I misplaced all of them!

After my college and my postgrad, I managed to work with an electric vehicle project (performance/status monitor through CAN bus), and my day job including power electronics and a brief stint of LED display panels. I have moved elsewhere, so I'm now doing embedded systems again after three years.

I still feel that I ain't doing enough. Therefore I sit around and read whatever it is on internet, forums, Hackaday and strolling in toy stores. They help me in giving ideas on how to improve coding and such.

I simplify by this: Learn the basics first - the C or some basic assembly. Then use it on the embedded system. Doing both together can be very difficult effort and I was lucky not to do that because I'm a pretty slow learner.
 
Top