i have a problem with pic18f452 and uart
i use simplest code like that:
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize
and between forever while loop i have this code
UART1_Write_Text("HELLO2");
Delay_ms(1000);
also i have in my hardware lcd module it works very fine but my received data on pc
is a scrap like that
???m
i have checked all connection sothand time nothing wrong also i have changed MAX232 ic but with no luck ?!
my hardware is like that
finall all my connections are ok (polarity and every thing else ?)
EDIT : i use mikroc as a compiler
Looks like a baud rate error. Have you checked that your oscillator settings are resulting in the expected frequency? Does the serial library you are using expect a certain clock frequency and you are sure that you are running at that frequency, or does it work over a set of frequencies and you have correctly informed the serial library what frequency you are using? Also it would be useful to see the byte received as a decimal or hex number rather than just ASCII.
What about the start bits, number of data bits, parity, and stop bits? Are they the same on both ends?
It happens when you have loose connections i.e. from max 232 to Pic & from max 232 to PC.
Try checking the fluctuations over the transmit pin or usr Oscilloscope to see the ASCII values of Hello World alphabets.
Related
This is driving me nuts for a couple of days now, so maybe you guys can give me some insights into what is going wrong.
I'm trying to read some data from an EEPROM (24LC16B) with an STM32(F0), but it just doesn't let me. I've tried an Arduino, which worked and does still work, so I do know that the wiring is correct.
This is my function to read the EEPROM data. (It is cut down to the very basis, just for testing): (Pastebin of my I2C_setup function)
uint16_t readEEPROMData(uint16_t deviceAddress, int memAddress){
// Wait while I2C peripheral is not ready
I2C_WaitForFlag(I2C_ISR_BUSY);
// Start I2C write transfer for 2 bytes, do not end transfer (SoftEnd_Mode)
I2C_TransferHandling(I2C1, 0xA2, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
I2C_WaitForFlag(I2C_ISR_TXIS);
// For testing purpose, be sure to generate a stop command...
I2C_TransferHandling(I2C1, 0xA2, 0, I2C_AutoEnd_Mode, I2C_Generate_Stop);
return I2C_COMM_STATUS;
}
Here's an pastebin of the Arduino library I used.
I've used a logic analyzer to see how the communication is going, and now I really don't understand it. Here's a printscreen of the working Arduino version:
And here's a printscreen of the STM32 communication:
Logic analyzer exports (viewable with Saleae Logic)
As you can see, I'm using the same address (although I had to use 0xA2 with the STM32), and there are no weird things happening, besides the NACK. So what could possible be wrong?
Confirm if all bus timing requirement are satisfied.
Confirm if their is adequate delay after every write cycle (5 mS)
Confirm is bus capacitance falls under permissible limit of I2C (400 pF - Theoretically).
Confirm if the correct VCC is supplied
As mentioned by you are interfacing EEPROM with MCU using cable you need to conform on capacitance.
You can use an oscilloscope to check if their are any distortion in waveform. You can use a LCR meter to check the capacitance.
Try reducing bus speed 25kHz to 50 kHz and check waveform.
Try increasing the strength of pull resister.
The problem with the wrong VCC capacity (4.2v instead of 5v for example) is, that the timing can be different to. (not fully verified, but it fixed the problem)
I'm trying to do something really simple and I'm having a bit of trouble getting it to work. I'm working with the MPL3115A2 Altitude/Pressure Sensor and a pic32 uC32 board, and I'm trying to communicate between the two using I2C. (uC32 board is similar enough to arduino that it's practically the same in terms of coding).
I'm using the wire library and I'm simply trying to read register 0x0C from the MPL3115A2, which should give me the device ID.
Here's a code snippet (the define is at the top of the code and the rest is in the main loop):
#define barAddress 0x60
Wire.beginTransmission(barAddress);
Wire.send(0x0C);
Wire.endTransmission();
Wire.requestFrom(barAddress, 1);
uint8_t a = Wire.receive();
Serial.println(a, HEX);
So I start the transmission with address 0x60 (From the datasheet: The standard 7-bit I2C slave address is 0x60 or 1100000. 8-bit read is 0xC1, 8-bit write is 0xC0.). Then I send 0x0C because that's the register I want to access. I then end transmission, and request 1 byte from address 0x60, receive that bit into a 8-bit variable, then print it.
The problem I run into is that when I print it, I just get 0. I don't get the device ID, just 0. No matter what register I try to read, I get 0.
I've been banging my head against a wall for the past few days trying to get this to work. I've attached something I've captured with a logic analyzer, as well as a list of registers from the datasheet of the MPL3115A2 that I've been trying to access.
Using a logic analyzer I can see the clock and data lines. The clock seems normal and the data line gives me the following:
START
Write['192'] + ACK
'12' + ACK
STOP
START
Read['193'] + ACK
'0' + NAK
STOP
This all seems correct to me (192 and 193 come from 8-bit write and read being 0xC0 and 0xC1), except for the '0'. I should be getting the device ID, not 0.
Thanks for any help with this!
You should look at Freescale's app note AN4481, which is referred to by the datasheet. Page 5 shows the single-byte read operation which is what you are doing, except that the register address write must not be followed by a STOP but instead uses a REPEATED-START.
I'm not familiar with the Wire library but it look like all you need to do is remove the Wire.endTransmission(); between the send and requestFrom.
Hopefully, this will solve your problem.
I am doing a project where i have to Interface to a serial device through RS232 COM1 port. I have set the BAUDRATE=9600, PORT=COM1, PARITY=None, Databits=8 but when I start to read data from the serial device it appears only series of square charecters.
I am working with VB.NET 2010
Kindly help.
Make sure you're reading the data properly -- if you know you're only going to be receiving hexadecimal bytes then you should be using the function Read(Byte(), Int32, Int32), which reads hexadecimal data.
Also, make sure your baud rate in your code matches the devices baud rate. Otherwise, you'll get strange data bytes.
I am working on GSM sim900D interfacing with Atmega16. Initially I made the circuit using MAX232 on breadboard. Then I connected it to my PC using a serial port. I tested AT commands, the commands worked perfectly on hyper terminal and I was able to send SMS using hyperterminal. Then I tested it on Proteus and it was working there perfectly too.
I am using codevision avr as the compiler. GSM work on 9600baud but the problem is that in compiler I have to keep the baud rate4800(clock = 1MHz) and at proteus COMPIM(physical baud=9600 & virtual baud=4800) only then it works when I run it on hardware(breadboard) it doesn't work as I have set the baud to 4800. I don't know how to set the baud for hardware. I tried 9600baud for hardware in compiler but it doesn't send SMS at all. Kindly tell me what I should do?
On ATmega16 (and other ATmegas), the serial baud rate is set via UBRRH and UBRRL registers plus the U2X bit in the UCSRA register. The detailed description of how this works starts on page 146 of the ATmega16 datasheet. Basically, UBRR is a 16-bit register and so must be accessed separately via 8 bit parts UBRRH (the high byte) and UBRRL (the low byte). The value you want to put into these registers (and the U2X bit in UCSRA register) depends on
the clock rate
the desired baud rate.
For 1Mhz clock and 9600 baud there are two options (see table 68 on page 168 in the datasheet): cleared U2X bit and UBRR set to 6 or set U2X and UBRR set to 12. The latter option results in a baud rate generation that is closer to the desired baud rate (0.2%) error, therefore, the latter option is recommended. Consequently, the code you want is:
UBRRH = 0;
UBRRL = 12;
UCSRA |= 1<<(U2X);
There is a nasty gotcha lurking here: as the datasheet states, UBRRH and UCSRC are the same register. UCSRC controls parity, stop bits, and other important settings. Therefore if you ever need to write to UCSRC, make sure that you set the URSEL bit at the same time:
UCSRC = (1<<URSEL) | (...other bits...)
or
UCSRC |= (1<<URSEL) | (...other bits...)
Otherwise you will clobber your UBRRH register and wonder why your baud rate is not what you expected.
But you can also make use of the AVR Libc code, which provides a read-made way for setting a baud rate on AVR, see util/setbaud.html
you check data sheet the error rate is too high. when you using 9600 baud rate on 1MHZ this is the main problem . take 8,12,16 MHZ as possible and check data sheet . and dont forget to burn fuse bits related to XTAL frequency if you not burn these bits properly that relate with crystal that is not work properly .
if u need more help ask..
I'm new to microcontroller programming and I have interfaced my microcontroller board to another device that provides a status based on the command send to it but, this status is provided on the same I/O pin that is used to provide data. So basically, I have an 8-bit data line that is used as an output from the microcontroller, but for certain commands I get a status back on one of the data lines if I choose to read it. So I would be required to change the direction of this one line to read the status thus converting this line as an ouput to an input and then back to an output. Is this acceptable programming or will this changing of the I/O pin this frequently cause instability?
Thanks.
There should not be any problem with changing the direction of the I/O line to read the status returned by the peripheral provided that you change the state of the line to an input before the peripheral starts to drive the line and then do not try to drive the line as an output until the peripheral stops driving it. What you must try to avoid is contention between the two driver devices, i.e. having the two ends being driven to opposite states by the processor and peripheral. This would result in, at best a large spike in the power consumption or worse blown pin driver circuitry in the processor, peripheral or both.
You do not say what the processor or peripheral are so I cannot tell whether there are any control bits in the interface that enable the remote device to output the status so that you can know whether the peripheral is driving the line at any time.
I've done this on digital I/O pins without any problems but I'm very far from an expert on this. It probably depends entirely on which microcontroller you are using though.
Yes, it's perfectly fine to change I/O direction on microcontroller repeatedly.
That's the standard method of communicating over open-collector buses such as I2C and the iButton. (see PICList: busses for links to assembly-language code examples).
transmit 0 bit: set output LATx bit to 0, and then set TRISx bit to OUTPUT.
transmit 1 bit: keep output LATx bit at 0, and set TRIS bit to INPUT (let external resistor pull-up line to high)
listen for response from peripheral: keep output LATx bit at 0, and set TRIS bit to INPUT. Let external resistor pull-up line to high when peripheral is transmitting a 1, or let the peripheral pull the line low when peripheral is transmitting a 0. Read the bit from the PORTx pin.
If both ends of the bus correctly follow this protocol (in particular, if neither end actively drives the line to high), then you never have to worry about contention or current spikes.
It`s important to remember that any IO switching in high speed generates EMI.
Depending of switching frequency, board layout and devices sensibilities, this EMI can affect performance and reliability of your application.
If you are having problems in your application use an oscilloscope to check for irradiated EMI in your board lanes.