0
\$\begingroup\$

I was trying to read 16bit ADC ad7705 by atmega32 and send the value read through SPI communication of atmega32 to real-term software by using UART of atmega32. I found that there was no transmission of data. However, when I wrote a separate program for atmega32 with its UART only(no use of SPI in the atmega32 program), it was sending data in real-term. Can anyone look into this problem and advise me the necessary steps for making SPI and UART of atmega32 work together?

\$\endgroup\$
  • \$\begingroup\$ There isn't any reason they wouldn't work together? It would seem like you didn't initialize your libraries properly or maybe your programmer is using the UART? You need to look at what your software is doing wrong. \$\endgroup\$ – hekete Jun 4 at 6:55
  • 1
    \$\begingroup\$ Please provide a short program example that demonstrates the problem. Also identify the compiler software and version you are using to compile your source code--e.g., AVR Studio, avr-gcc, CodeVision, ImageCraft, CrossWorks, WinAVR, etc. Without this information we can only guess what the problem might be and that wastes time. Note that the ATmega328P's USART can be used in master SPI mode; see section 21 "USART in SPI Mode" in the ATmega328P's data sheet (ww1.microchip.com/downloads/en/DeviceDoc/…). \$\endgroup\$ – Jim Fischer Jun 4 at 9:17
  • \$\begingroup\$ @JimFischer I have used Atmel Studio version 7 \$\endgroup\$ – Rudrendu Mahindar Jun 5 at 6:26
  • \$\begingroup\$ @JimFischer please check the above code that I have used \$\endgroup\$ – Rudrendu Mahindar Jun 6 at 13:07
  • \$\begingroup\$ Can you take the few minutes necessary to edit your question and appropriately format it? Also, it's somewhat rude to ask an individual participant to check your code. The poster has participated at the level he sees fit, and would do more if he wanted to. If you want an answer, try making the question easier to answer. \$\endgroup\$ – Scott Seidman Jun 6 at 13:38
3
\$\begingroup\$

Some general comments.

  1. When composing a message on StackExchange's Electrical Engineering website, notice the question mark icon '?' at the top right corner of the toolbar above the message editing box. Click on that question mark to display the Markdown help webpage. Scroll down the Markdown help webpage to find the section titled "Syntax highlighting for code". Use the information in that section to learn how to properly embed within your message a source code listing that has syntax highlighting. For example:
#include <iostream>
int main()
{
    std::cout << "Hello, World!" << std::endl;
    return 0;
}
  1. Read and try to understand the applicable data sheet(s) before asking others to spend their time helping you. The data sheet for Microchip Technology's ATmega328P microcontroller is provided on Microchip Technology's website:

http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf

  1. Look at Figure 1.1 "Pinout ATmega48A/PA/88A/PA/168A/PA/328/P" (page 12) in the ATmega328P data sheet. Write down the port B pin numbers (PBn) for the following signals as shown in Figure 1.1: MISO, MOSI, SCK, SS. Now look at your function 'spi_init_master', at the code that sets and clears individual bits within port B's data direction register (DDRB): is your code setting and clearing the correct bit (PBn) numbers in DDRB?
MISO (INPUT)  PB?
MOSI (OUTPUT) PB?
SCK  (OUTPUT) PB?
SS   (OUTPUT) PB?
  1. As a best practice, replace every magic number in your source code with a descriptive name (see self-documenting code). For example, add a header file named "my_defs.h" to your project and in that header file define some preprocessor macros that correspond to the CPU register names, I/O port bit positions, etc. for SPI bus related programming tasks. Include that header file into your C source files, and in your C code use your preprocessor macros instead of the hard-coded register names, pin numbers, etc.
/*
 * my_defs.h
 *
 * Created: 6/7/2019 3:44:31 AM
 *  Author: me
 */ 

#ifndef MY_DEFS_H_
#define MY_DEFS_H_

#define BIT_SET(VALUE, BIT_POSITION) ((VALUE) |= (1<<(BIT_POSITION)))
#define BIT_CLEAR(VALUE, BIT_POSITION) ((VALUE) &= ~(1<<(BIT_POSITION)))

/* PIN_MODE(PIN_NAME, IO_MODE)
 *  PIN_NAME = { MISO | MOSI | SCK | SS | ... }
 *  IO_MODE = { INPUT | OUTPUT }
 */
#define PIN_MODE(PIN_NAME, IO_MODE) (PIN_MODE_ ## IO_MODE(PIN_NAME ## _DDR, PIN_NAME ## _BIT))
#define PIN_MODE_OUTPUT(DDR, BIT_POSITION) BIT_SET(DDR, BIT_POSITION)
#define PIN_MODE_INPUT(DDR, BIT_POSITION) BIT_CLEAR(DDR, BIT_POSITION)

#ifdef __AVR_ATmega328P__

#define MISO_DDR DDRB
#define MISO_PORT PORTB
#define MISO_PIN PINB
#define MISO_BIT 4

#define MOSI_DDR DDRB
#define MOSI_PORT PORTB
#define MOSI_PIN PINB
#define MOSI_BIT 3

#define SCK_DDR DDRB
#define SCK_PORT PORTB
#define SCK_PIN PINB
#define SCK_BIT 5

#define SS_DDR DDRB
#define SS_PORT PORTB
#define SS_PIN PINB
#define SS_BIT 2

#endif /* __AVR_ATmega328P__ */

#endif /* MY_DEFS_H_ */
/*
 * main.c
 */

#include <avr/io.h>
#define F_CPU 16000000UL
#include "my_defs.h"

void
spi_bus_initialize()
{
    // Configure the SPI bus's MOSI, SCK, and SS pins as outputs
    PIN_MODE(MOSI, OUTPUT);
    PIN_MODE(SCK, OUTPUT);
    PIN_MODE(SS, OUTPUT);

    // Configure the SPI bus's MISO pin as an input
    PIN_MODE(MISO, INPUT);

    // Set the SPI bus's slave select signal (logic high == idle).
    BIT_SET(SS_PORT, SS_BIT);

    /* Other configuration tasks, e.g.,
     *    Master mode select
     *    Clock polarity, phase, and frequency
     *    etc...
     */

    // Enable the microcontroller's SPI bus circuitry
    BIT_SET(SPCR, SPE);
}

/* ... */
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.