Прошу вашего совета по следующему вопросу…
У меня есть двухканальный передатчик, позволяющий взаимодействовать с ним по SPI протоколу, Имею в наличии нечто вроде протокола информационного взаимодействия. В качестве “железки” для работы по указанному протоколу я решил использовать Raspberry Pi 2. Задача вроде бы вполне решаемая этими средствами и применением Python.
Параметры обмена: CPOL=0, CPHA=1. Период обмена 2,5 мс. Частота – 500 кГц..10 МГц.
Состав слов MOSI:
1 байт - 6 бит контрольное слово (checkword), полученное от передатчика в предыдущем цикле обмена + 2 бита - установка уровня выходной мощности (полная мощность, -3 дБ, -6 дБ, -9 дБ).
3 байт - кодовое слово, передаваемое в передатчик для подтверждения целостности канала.
2,4,5,6 байты - резерв, не используются
Состав слов MISO:
1 байт - 6 бит контрольное слово (передаваемое передатчиком) + 1 бит подтверждение запроса + 1 бит признак исправности.
2 байт - выходная мощность основного канала (Pout_o в моей программе).
3 байт - выходная мощность резервного канала (Pout_k в моей программе).
4 байт - контрольное слово, полученное от стенда.
5 байт - коэффициент стоячей волны по основному каналу (KSV_o в моей программе).
6 байт - коэффициент стоячей волны по резервному каналу (KSV_k в моей программе).
Вот мой код:
import spidev
import time
import math
import random
from tkinter import *
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 110000
spi.bits_per_word = 8
spi.mode = 0b00
spi.cshigh = False
#spi.loop = True
root = Tk()
root.title("SPI-CONFIG")
root.geometry("500x300+600+300")
def printer(event):
print("SPI-test")
def Pout(sec_byte):
P=100*(10**(0.0058*sec_byte))
return P
def KSV(fifth_byte):
k=1+0.1*fifth_byte
return k
var=IntVar()
radbut1 = Radiobutton(root,variable=var,text = "3 dB",value=1)
radbut2 = Radiobutton(root,variable=var,text = "6 dB",value=2)
radbut3 = Radiobutton(root,variable=var,text = "9 dB",value=3)
radbut3.pack(side=BOTTOM)
radbut2.pack(side=BOTTOM)
radbut1.pack(side=BOTTOM)
KSV_o=StringVar()
P_o=StringVar()
P_k=StringVar()
lab_P_o = Label(root, textvariable=P_o)
lab_P_o.pack(side=TOP)
lab_P_k = Label(root,textvariable=P_k)
lab_P_k.pack(side=TOP)
lab_KSV_o = Label(root, textvariable=KSV_o)
lab_KSV_o.pack(side=TOP)
b_in_0 = 0
def callback(event=None):
global b_in_0
Pset=0b00000011
b_out_0 = (b_in_0 << 2) + int(Pset) ## Control word TRMTT - answer
b_out_1 = 0xAA #in_dat_0[2] ## Reserve
b_out_2 = 0xAB #in_dat_0[3] ## Control word RPi
b_out_3 = 0xAD #in_dat_0[4] ## Reserve
b_out_4 = 0xFA #in_dat_0[5] ## Reserve
b_out_5 = 0xFB #in_dat_0[6] ## Reserve
b_out_6 = 0xFC #in_dat_0[7] ## Reserve
b_out_7 = 0xFD #in_dat_0[8] ## Reserve
out_dat= spi.writebytes([b_out_0,b_out_1,b_out_2,b_out_3,b_out_4,b_out_5])
in_dat = spi.readbytes(6)
b_in_0 = int(in_dat[0]) >> 2 ## Control word TRMTT
b_in_1 = 100*(10**(0.0058*int(in_dat[1]))) ## Pout_o
b_in_2 = 100*(10**(0.0058*in_dat[4]))#in_dat[2] ## Pout_k
b_in_3 = in_dat[3] ## Control word RPi
b_in_4 = in_dat[4] ## KSV_0
b_in_5 = in_dat[5] ## KSV_k
KSV_o.set('KSV = '+ str(b_in_5))
P_o.set('Pout_o = '+ str(b_in_1))
P_k.set('Pout_k = '+ str(b_in_2))
#lab_P_o.after(50,callback)
#lab_P_k.after(50,callback)
lab_KSV_o.after(50,callback)
#print(in_dat)
lab_P_o.after(50,callback)
lab_P_k.after(50,callback)
lab_KSV_o.after(50,callback)
root.mainloop()
Итак, теперь о проблеме…. Данные пишутся и читаются, но… Неодновременно! Насколько я понял суть SPI протокола, чтение по команде “spi.readbytes” должно начаться с первым битом сообщения, переданного по команде spi.writebytes. У меня же картина другая - сначала все байты записываются, потом читаются, всилу чего информационный полнодуплексный обмен невозможен. Вот осциллограмма обмена (желтый - MOSI, пурпурный - MISO, синий - SCLK) :
Your text to link here…
Я подумал, что не помешает замкнуть выход расберри со входом и посмотреть, будет ли идти прием. Оказалось, нет. Соответственно, передатчик тут не при чем. Никак не пойму, где в моем кривом коде ошибка?